

Almost every application needs to communicate with the user in some way.
Therefore, a substantial part of the code deals with the interaction
of program logic with GUI components.

Typically, the following is needed:

 put values into input fields under program control
 read and check input from the user
 pop up dialogs to query the user for further information


Task

For a minimal "application", write a program that presents a form with three components to the user:

 a numeric input field ("Value") 
 a button ("increment")
 a button ("random")


The field is initialized to zero.

The user may manually enter a new value into the field,
or increment its value with the "increment" button.

Entering a non-numeric value should be either impossible,
or issue an error message.

Pressing the "random" button presents a confirmation dialog,
and resets the field's value to a random value if the answer is "Yes".

(This task may be regarded as an extension of the task Simple windowed application).



OPTION GUI TRUE
PRAGMA GUI gtk3
 
DECLARE (*show)() = gtk_widget_show_all TYPE void
DECLARE (*hide)() = gtk_widget_hide TYPE void
 
gui = GUIDEFINE(" \
    { type=WINDOW name=window callback=delete-event title=\"Rosetta Code\" width-request=200 } \
    { type=BOX name=box parent=window orientation=GTK_ORIENTATION_VERTICAL } \
    { type=SPIN_BUTTON name=spin parent=box numeric=TRUE } \
    { type=BUTTON_BOX name=bbox parent=box } \
    { type=BUTTON name=increment parent=bbox callback=clicked label=\"Increment\" } \
    { type=BUTTON name=random parent=bbox callback=clicked label=\"Random\" } \
    { type=MESSAGE_DIALOG name=confirm callback=delete-event callback=response,yesno message-type=GTK_MESSAGE_WARNING buttons=GTK_BUTTONS_YES_NO title=\"Warning\" text=\"Get random number?\" }")
 
CALL GUISET(gui, "spin", "adjustment", gtk_adjustment_new(0, 0, MAXNUM(float), 1, 1, 0))
 
DECLARE answer TYPE int*
DECLARE input TYPE FLOATING
 
WHILE TRUE
    event$ = GUIEVENT$(gui, TRUE)
    SELECT TOKEN$(event$, 1)
        CASE "window"
            BREAK
        CASE "increment"
            CALL GUIGET(gui, "spin", "value", &input)
            CALL GUISET(gui, "spin", "value", input+1)
        CASE "random"
            CALL GUIFN(gui, "confirm", show)
        CASE "yesno"
            answer = (intptr_t)DEC(TOKEN$(event$, 2))
            IF *answer = GTK_RESPONSE_YES THEN CALL GUISET(gui, "spin", "value", RANDOM(MAXNUM(float)))
            CALL GUIFN(gui, "confirm", hide)
    ENDSELECT
WEND