

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).



 
;; Using the LTK library...
 
(defun gui-test ()
  "the main window for the input test"
  (ltk:with-ltk ()
    (ltk:wm-title ltk:*tk* "GUI Test")
    (ltk:bind ltk:*tk* "<Alt-q>" (lambda (evt)
				   (declare (ignore evt))
				   (setf ltk:*exit-mainloop* t)))
    (let* (;; Initializing random generator
	   (*random-state* (make-random-state t))
	   ;; Creating widgets
	   (the-input (make-instance 'ltk:entry
				     :text "0"
				     :validate :key))
	   (f (make-instance 'ltk:frame))
	   (btn1 (make-instance 'ltk:button :text "random" :master f))
	   (btn2 (make-instance 'ltk:button :text "increment" :master f)))
      ;; Associating actions with widgets
      (ltk:bind btn1 "<Button-1>"
		(lambda (evt)
		  (declare (ignore evt))
		  (when (ltk:ask-yesno "Really reset to random?" :title "Question")
		    (setf (ltk:text the-input) (write-to-string (random 10000))))))
      (ltk:bind btn2 "<Button-1>"
		(lambda (evt)
		  (declare (ignore evt))
		  (setf (ltk:text the-input)
			(write-to-string (1+ (parse-integer (ltk:text the-input)))))))
      (ltk:format-wish "~A configure -validatecommand {string is int %P}"
		       (ltk:widget-path the-input))
      (ltk:focus the-input)
      ;; Placing widgets on the window
      (ltk:pack the-input :side :top)
      (ltk:pack f :side :bottom)
      (ltk:pack btn1 :side :left)
      (ltk:pack btn2 :side :right))))
 
(gui-test)
 
 