-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathtask-5.rkt
executable file
·52 lines (42 loc) · 2.37 KB
/
task-5.rkt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#! /usr/bin/env gracket
#lang at-exp racket/gui
;; a create-read-update-deleted MVC implementation
;; ---------------------------------------------------------------------------------------------------
(require 7GUI/Macros/7guis 7GUI/Macros/7state)
;; ---------------------------------------------------------------------------------------------------
(define (selector! nu) (set! *prefix nu))
(define (select s) (string-prefix? s *prefix))
(define (data->selected! _) (set! *selected (if (string=? "" *prefix) *data (filter select *data))))
(define-state *data '("Emil, Hans" "Mustermann, Max" "Tisch, Roman") data->selected!)
(define-state *prefix "" data->selected!)
(define-state *selected *data (λ (s) (send lbox set s))) ;; selected = (filter select data)
(define (Create *data) (append *data (list (get-name))))
(define (Update i) (if i (operate-on i (curry cons (get-name))) none))
(define (Delete i) (if i (operate-on i values) none))
#; {N [[Listof X] -> [Listof X]] -> [Listof X]}
;; traverse list to the i-th position of selected in data, then apply operator to rest (efficiency)
;; ASSUME selected = (filter selector data)
;; ASSUME i <= (length selected)
(define (operate-on i operator)
(let sync ((i i) (data *data) (selected *selected))
(if (select (first data))
(if (zero? i)
(operator (rest data))
(cons (first data) (sync (sub1 i) (rest data) (rest selected))))
(cons (first data) (sync i (rest data) selected)))))
(define (get-name) (string-append (send surname get-value) ", " (send name get-value)))
;; ---------------------------------------------------------------------------------------------------
(define (mk-changer p) (with i #:post p #:widget lbox #:method get-selection i))
(define (name-field% n) (class text-field% (super-new (label n) (init-value "") (min-width 200))))
(define-gui frame "CRUD"
(#:horizontal
(#:vertical
(text-field% #:change *prefix (with p p) [label "Filter prefix: "][init-value ""])
(#:id lbox list-box% [label #f][choices '()][min-width 100][min-height 100]))
(#:vertical (#:id name (name-field% "Name: ")) (#:id surname (name-field% "Surname: "))))
(#:horizontal
(button% #:change *data (just Create) [label "Create"])
(button% #:change *data (mk-changer Update) [label "Update"])
(button% #:change *data (mk-changer Delete) [label "Delete"])))
(selector! "")
(send frame show #t)