(import scheme) (import (chicken base)) (import (chicken format)) (import (chicken pathname)) (import (chicken process-context)) (import gtk-server) (define gtk-server (start-gtk-server!)) (define (gtk #!rest args) (apply gtk-send! gtk-server args)) (gtk "gtk_init" 'NULL 'NULL) (gtk "gtk_server_define gtk_builder_new_from_file NONE WIDGET 1 STRING") (gtk "gtk_server_define gtk_builder_get_object NONE WIDGET 2 WIDGET STRING") (define widget #f) ;; Get GUI definition (define ui-file (pathname-replace-extension (program-name) ".ui")) (define xml (gtk "gtk_builder_new_from_file" ui-file)) ;; Get main window ID and connect signal (set! widget (gtk "gtk_builder_get_object" xml "window")) (gtk "gtk_server_connect" widget "delete-event" "window") ;; Get button ID's and connect signals (set! widget (gtk "gtk_builder_get_object" xml "button0")) (gtk "gtk_server_connect" widget "clicked" "button0") (set! widget (gtk "gtk_builder_get_object" xml "button1")) (gtk "gtk_server_connect" widget "clicked" "button1") (set! widget (gtk "gtk_builder_get_object" xml "button2")) (gtk "gtk_server_connect" widget "clicked" "button2") (set! widget (gtk "gtk_builder_get_object" xml "button3")) (gtk "gtk_server_connect" widget "clicked" "button3") (set! widget (gtk "gtk_builder_get_object" xml "button4")) (gtk "gtk_server_connect" widget "clicked" "button4") (set! widget (gtk "gtk_builder_get_object" xml "button5")) (gtk "gtk_server_connect" widget "clicked" "button5") (set! widget (gtk "gtk_builder_get_object" xml "button6")) (gtk "gtk_server_connect" widget "clicked" "button6") (set! widget (gtk "gtk_builder_get_object" xml "button7")) (gtk "gtk_server_connect" widget "clicked" "button7") (set! widget (gtk "gtk_builder_get_object" xml "button8")) (gtk "gtk_server_connect" widget "clicked" "button8") (set! widget (gtk "gtk_builder_get_object" xml "button9")) (gtk "gtk_server_connect" widget "clicked" "button9") ;; Operators (set! widget (gtk "gtk_builder_get_object" xml "buttonC")) (gtk "gtk_server_connect" widget "clicked" "buttonC") (set! widget (gtk "gtk_builder_get_object" xml "buttonCE")) (gtk "gtk_server_connect" widget "clicked" "buttonCE") (set! widget (gtk "gtk_builder_get_object" xml "buttonAdd")) (gtk "gtk_server_connect" widget "clicked" "buttonAdd") (set! widget (gtk "gtk_builder_get_object" xml "buttonMinus")) (gtk "gtk_server_connect" widget "clicked" "buttonMinus") (set! widget (gtk "gtk_builder_get_object" xml "buttonMul")) (gtk "gtk_server_connect" widget "clicked" "buttonMul") (set! widget (gtk "gtk_builder_get_object" xml "buttonDiv")) (gtk "gtk_server_connect" widget "clicked" "buttonDiv") (set! widget (gtk "gtk_builder_get_object" xml "buttonEq")) (gtk "gtk_server_connect" widget "clicked" "buttonEq") ;; Memory buttons (set! widget (gtk "gtk_builder_get_object" xml "buttonMemadd")) (gtk "gtk_server_connect" widget "clicked" "buttonMemadd") (set! widget (gtk "gtk_builder_get_object" xml "buttonMemread")) (gtk "gtk_server_connect" widget "clicked" "buttonMemread") ;; Get entry ID (define entry (gtk "gtk_builder_get_object" xml "entry")) ;; Calculator starts with 0 (gtk "gtk_entry_set_text" entry 0) ;;; Init variables (define state 0) ; Initialize calculator state (define cache 0) ; Initialize temp calculator cache (define action 0) ; Initialize last calculator action (define total 0) ; Initialize calculator total result (define mem 0) ; Initialize MEM function ;;; Functions ;; Define action when +, -, *, or / is pressed (define (operator-key) (define (// a b) (inexact->exact (floor (/ a b)))) (when (= state 0) (case action ((1) (set! cache (+ cache (string->number (gtk "gtk_entry_get_text" entry)))) (gtk "gtk_entry_set_text" entry cache)) ((2) (set! cache (- cache (string->number (gtk "gtk_entry_get_text" entry)))) (gtk "gtk_entry_set_text" entry cache)) ((3) (set! cache (* cache (string->number (gtk "gtk_entry_get_text" entry)))) (gtk "gtk_entry_set_text" entry cache)) ((4) (if (zero? (string->number (gtk "gtk_entry_get_text" entry))) (gtk "gtk_entry_set_text" entry "ERROR") (begin (set! cache (// cache (string->number (gtk "gtk_entry_get_text" entry)))) (gtk "gtk_entry_set_text" entry cache))))))) ;; Define action when 0 1 2 3 4 5 6 7 8 9 is pressed; requires argument (define (number-key arg) (let ((number (gtk "gtk_entry_get_text" entry))) (if (or (equal? number "0") (> state 0)) (begin (set! cache (string->number number)) (gtk "gtk_entry_set_text" entry arg)) (gtk "gtk_entry_set_text" entry (string-append number arg))) (set! state 0))) ;; Mainloop (let loop () (let ((event (gtk "gtk_server_callback wait"))) (when (not (equal? event "window")) (cond ((equal? event "buttonMemread") (set! state 0) (set! cache (string->number (gtk "gtk_entry_get_text" entry))) (gtk "gtk_entry_set_text" entry mem)) ((equal? event "buttonMemadd") (set! mem (gtk "gtk_entry_get_text" entry))) ((equal? event "buttonC") (gtk "gtk_entry_set_text" entry 0)) ((equal? event "buttonCE") (set! total 0) (set! state 0) (set! action 0) (set! cache 0) (set! mem 0) (gtk "gtk_entry_set_text" entry 0)) ((equal? event "buttonAdd") (operator-key) (set! action 1) (set! state (+ state 1))) ((equal? event "buttonMinus") (operator-key) (set! action 2) (set! state (+ state 1))) ((equal? event "buttonMul") (operator-key) (set! action 3) (set! state (+ state 1))) ((equal? event "buttonDiv") (operator-key) (set! action 4) (set! state (+ state 1))) ((equal? event "buttonEq") (operator-key) (set! action 0) (set! state (+ state 1))) ((member event '("button0" "button1" "button2" "button3" "button4" "button5" "button6" "button7" "button8" "button9")) (number-key (string (string-ref event 6))))) (loop)))) ;; Exit GTK (gtk "gtk_server_exit") (stop-gtk-server! gtk-server)