MODULE test_inputs ; (* m2-GTK4 test - the input widgets and their get/set + signals. Exercises GtkEntry/GtkEditable, GtkCheckButton, GtkSwitch, GtkScale and GtkRange: sets values, reads them back, then emits the signals programmatically and checks the handlers ran. Requires a display. *) FROM Gio IMPORT g_application_run, g_application_quit; FROM GtkApplication IMPORT gtk_application_new; FROM GtkWindow IMPORT gtk_application_window_new, gtk_window_set_child; FROM GtkBox IMPORT gtk_box_new, gtk_box_append, gtk_box_set_spacing; FROM GtkEnums IMPORT GtkVertical, GtkHorizontal; FROM GtkEntry IMPORT gtk_entry_new, gtk_entry_set_placeholder_text, gtk_entry_get_text_length; FROM GtkEditable IMPORT gtk_editable_set_text, gtk_editable_get_text, gtk_editable_set_editable, gtk_editable_get_editable; FROM GtkCheckButton IMPORT gtk_check_button_new_with_label, gtk_check_button_set_active, gtk_check_button_get_active; FROM GtkSwitch IMPORT gtk_switch_new, gtk_switch_set_active, gtk_switch_get_active, gtk_switch_set_state, gtk_switch_get_state; FROM GtkScale IMPORT gtk_scale_new_with_range, gtk_scale_set_digits; FROM GtkRange IMPORT gtk_range_set_value, gtk_range_get_value; FROM GObject IMPORT g_signal_emit_by_name; FROM GtkUtils IMPORT Connect, CStrToM2; FROM SYSTEM IMPORT ADDRESS, ADR; FROM libc IMPORT printf; CONST AppId = "org.example.m2gtk4.TestInputs"; VAR app, entry, check, sw, scale: ADDRESS; entryChanged, toggled, valueChanged: BOOLEAN; passed: BOOLEAN; PROCEDURE OnChanged (editable: ADDRESS; data: ADDRESS); BEGIN entryChanged := TRUE END OnChanged; PROCEDURE OnToggled (button: ADDRESS; data: ADDRESS); BEGIN toggled := TRUE END OnToggled; PROCEDURE OnValue (range: ADDRESS; data: ADDRESS); BEGIN valueChanged := TRUE END OnValue; PROCEDURE OnActivate (application: ADDRESS; data: ADDRESS); VAR window, box: ADDRESS; got: ARRAY [0..63] OF CHAR; ok: BOOLEAN; BEGIN ok := TRUE; entryChanged := FALSE; toggled := FALSE; valueChanged := FALSE; (* --- GtkEntry / GtkEditable --- *) entry := gtk_entry_new(); gtk_entry_set_placeholder_text(entry, "name"); Connect(entry, "changed", ADR(OnChanged), NIL); gtk_editable_set_text(entry, "hello"); CStrToM2(gtk_editable_get_text(entry), got); IF (got[0] # 'h') OR (got[4] # 'o') OR (got[5] # 0C) THEN printf("entry text wrong: [%s]\n", got); ok := FALSE END; IF gtk_entry_get_text_length(entry) # 5 THEN printf("entry length wrong\n"); ok := FALSE END; gtk_editable_set_editable(entry, 0); IF gtk_editable_get_editable(entry) # 0 THEN printf("editable flag wrong\n"); ok := FALSE END; (* --- GtkCheckButton --- *) check := gtk_check_button_new_with_label("Enable"); Connect(check, "toggled", ADR(OnToggled), NIL); gtk_check_button_set_active(check, 1); IF gtk_check_button_get_active(check) # 1 THEN printf("check active wrong\n"); ok := FALSE END; (* --- GtkSwitch --- *) sw := gtk_switch_new(); gtk_switch_set_active(sw, 1); IF gtk_switch_get_active(sw) # 1 THEN printf("switch active wrong\n"); ok := FALSE END; gtk_switch_set_state(sw, 0); IF gtk_switch_get_state(sw) # 0 THEN printf("switch state wrong\n"); ok := FALSE END; (* --- GtkScale / GtkRange --- *) scale := gtk_scale_new_with_range(GtkHorizontal, 0.0, 10.0, 1.0); gtk_scale_set_digits(scale, 1); Connect(scale, "value-changed", ADR(OnValue), NIL); gtk_range_set_value(scale, 4.0); IF ABS(gtk_range_get_value(scale) - 4.0) > 0.001 THEN printf("scale value wrong\n"); ok := FALSE END; (* the setters may already have emitted; emit explicitly to be sure *) g_signal_emit_by_name(entry, "changed"); g_signal_emit_by_name(check, "toggled"); g_signal_emit_by_name(scale, "value-changed"); IF NOT entryChanged THEN printf("changed did not fire\n"); ok := FALSE END; IF NOT toggled THEN printf("toggled did not fire\n"); ok := FALSE END; IF NOT valueChanged THEN printf("value-changed did not fire\n"); ok := FALSE END; (* assemble everything to exercise the container path too *) box := gtk_box_new(GtkVertical, 6); gtk_box_set_spacing(box, 6); gtk_box_append(box, entry); gtk_box_append(box, check); gtk_box_append(box, sw); gtk_box_append(box, scale); window := gtk_application_window_new(application); gtk_window_set_child(window, box); passed := ok; g_application_quit(application) END OnActivate; VAR rc: INTEGER; BEGIN passed := FALSE; app := gtk_application_new(AppId, 0); IF app = NIL THEN printf("test_inputs: FAIL (no app)\n"); HALT(1) END; Connect(app, "activate", ADR(OnActivate), NIL); rc := g_application_run(app, 0, NIL); IF passed THEN printf("test_inputs: PASS\n"); HALT(0) ELSE printf("test_inputs: FAIL\n"); HALT(1) END END test_inputs.