-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathexample_dragdrop_test.go
121 lines (100 loc) · 2.54 KB
/
example_dragdrop_test.go
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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
package lift_test
import (
"fmt"
"github.com/AndrewHarrisSPU/lift"
)
// This example shows a switch-based dispatch table, yielding different logic than a [Map] would.
func Example_c_eventhandlers() {
// brewing some dummy objects...
photo := &file{path: "tableflip.jif", data: "(╯°□°)╯︵ ┻━┻"}
home := &folder{path: "home", locked: false}
sys := &folder{path: "system", locked: true}
// brewing some dummy events...
events := []event{
newEvent(mouseClick{}, sys, lift.Empty{}),
newEvent(mouseClick{}, photo, lift.Empty{}),
newEvent(mouseDrop{}, photo, home),
newEvent(mouseDrop{}, photo, sys),
newEvent(mouseClick{}, home, lift.Empty{}),
}
for _, ev := range events {
eventDispatch(ev)
}
// Output:
// tableflip.jif:
// (╯°□°)╯︵ ┻━┻
// home:
// tableflip.jif
}
// GADGETS
type opFunc[OP any, SRC any, DST any] func(OP, SRC, DST) bool
type evFunc = func(event) bool
type event struct {
op, src, dst lift.Sym
signature lift.Sym
}
func newEvent[OP any, SRC any, DST any](op OP, src SRC, dst DST) event {
return event{
op: lift.Wrap(op),
src: lift.Wrap(src),
dst: lift.Wrap(dst),
signature: lift.T[opFunc[OP, SRC, DST]](),
}
}
func liftHandler[OP any, SRC any, DST any](fn opFunc[OP, SRC, DST]) evFunc {
return func(ev event) bool {
op, opOk := lift.Unwrap[OP](ev.op)
src, srcOk := lift.Unwrap[SRC](ev.src)
dst, dstOk := lift.Unwrap[DST](ev.dst)
if !opOk || !srcOk || !dstOk {
return false
}
return fn(op, src, dst)
}
}
// DUMMY TYPES
// dummy mouse event types
type mouseClick struct{}
type mouseDrop struct{}
// dummy file types
type file struct {
path, data string
}
type folder struct {
path string
locked bool
files []*file
}
// HANDLERS & DISPATCH
func rejectLockedFolder(ev event) (rejected bool) {
if dir, isDir := lift.Unwrap[*folder](ev.src); isDir && dir.locked {
return true
}
if dir, isDir := lift.Unwrap[*folder](ev.dst); isDir && dir.locked {
return true
}
return false
}
func openFile(op mouseClick, f *file, _ lift.Empty) bool {
fmt.Printf("%s:\n\t%s\n", f.path, f.data)
return true
}
func listFiles(op mouseClick, dir *folder, _ lift.Empty) bool {
fmt.Printf("%s:\n", dir.path)
for _, f := range dir.files {
fmt.Println("\t", f.path)
}
return true
}
func moveFile(op mouseDrop, f *file, dir *folder) bool {
dir.files = append(dir.files, f)
return true
}
func eventDispatch(ev event) {
switch {
case rejectLockedFolder(ev):
case liftHandler(openFile)(ev):
case liftHandler(listFiles)(ev):
case liftHandler(moveFile)(ev):
}
}