Search code examples
dialogdm-script

What does the format and width stand for in DLGCreateRealField


What does the format and the width stand for in the DLGCreateRealField(number value, number width, number format) dialog function? The documentation does not say anything about it.


Solution

  • TL;DR / Most cases

    The width is the display width of the input field in the dialog.

    The format tells how many digits in total to show keeping at least one digit after the decimal separator. The input is only formatted in the initial state and on the return value but only if the input is changed (with some more exceptions, see below). The user can type as many digits as she/he wants. The value is rounded. Example: For format=3 the value 1.234 is shown as 1.23; the value 123.456 is shown as 123.4.

    Note that there are some weird corner cases mentioned below.


    Unexpected behaviour summary

    1. Return value is only formatted/rounded correctly when the input is touched (otherwise 6 digits)
    2. Return value is not rounded if the input has exactly 6 digits before the decimal separator (no matter which format)
    3. The shown values are converted to exponent notation (e.g. 1.2e8) if the value is gerater than 100 000 000 (no matter which format)

    Details

    Example Dialog

    The image shows an example dialog created with the code below. The first three inputs have the width of 8, the last three inputs have the width of 16. This is easy to understand.

    Now the format: Each input has the format equal to its label. The first inputs format is 2, the last inputs format is 9. On creation the input shows as many digits as specified but at least one digit after the decimal separator. For the first input this is two digits in total. But because 12 already contains two digits, the first digit after the decimal separator is kept. All the other inputs show this behaviour as there are never more digits in total than specified. As you can see on Seven the number is rounded, not just cut off.

    The user can type in as many digits as she/he wants. (Only digits, e, minus and the dot are allowed. All characters after a second dot are ignored.)

    If the user does not change anything and presses OK, the returned value is rounded on 6 digits with the rules explained above. As soon as one touches the input (also type in one digit and then remove it immediately is enough), the input will be rounded on the format... Except if the value in the input has exactly 6 digits before the decimal separator. Then it is returned as an integer, the initial value is still formatted correctly. Phew...

    Note that on some point the numbers are converted to the exponential notation. Also in the input field! This means the value 123456789 is shown as 1.23456789e+8. The exponent notation follows the format rules again (not counting the exponent digits). This means in the first input field with format=2 the value is shown as 1.2e+8.

    The following code was used to create the screenshot.

    TagGroup DLG, DLGItems;
    
    DLG = DLGCreateDialog( "Please enter values", DLGItems);
    
    TagGroup val2tg, val3tg, val4tg, val5tg, val7tg, val9tg;
    
    DLGitems.DLGAddElement(DLGCreateRealField("Two:  ", val2tg, 12.123456789123, 8, 2));
    DLGitems.DLGAddElement(DLGCreateRealField("Three:", val3tg, 12.123456789123, 8, 3));
    DLGitems.DLGAddElement(DLGCreateRealField("Four: ", val4tg, 12.123456789123, 8, 4));
    DLGitems.DLGAddElement(DLGCreateRealField("Five: ", val5tg, 12.123456789123, 16, 5));
    DLGitems.DLGAddElement(DLGCreateRealField("Seven:", val7tg, 12.123456789123, 16, 7));
    DLGitems.DLGAddElement(DLGCreateRealField("Nine: ", val9tg, 12.123456789123, 16, 9));
    
    object dialog = alloc(UIFrame).init(DLG);
    if(dialog.pose()){
        Result("\n= = =\n");
        Result("Two:   " + val2tg.DLGGetValue() + "\n");
        Result("Three: " + val3tg.DLGGetValue() + "\n");
        Result("Four:  " + val4tg.DLGGetValue() + "\n");
        Result("Five:  " + val5tg.DLGGetValue() + "\n");
        Result("Seven: " + val7tg.DLGGetValue() + "\n");
        Result("Nine:  " + val9tg.DLGGetValue() + "\n");
    }