forked from kennytilton/qooxlisp
-
Notifications
You must be signed in to change notification settings - Fork 1
/
control.lisp
146 lines (110 loc) · 4.07 KB
/
control.lisp
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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
;; -*- mode: Lisp; Syntax: Common-Lisp; Package: qooxlisp; -*-
#|
control -- abstract control handling
(See package.lisp for license and copyright notigification)
|#
(in-package :qxl)
(export! control enabled ^enabled ct-action-lambda sound ^sound
tool-tip tool-tip-show? click-evt ^click-evt ^mouse-over? mouse-over?)
(defmd control ()
(ct-proxy (c? self))
(title$ (c? (format nil "~:(~a~)" ;; this is just a poor default-- really s.b. supplied by form author
(string-downcase (substitute #\space #\- (string (md-name self)))))))
(ct-action nil :cell nil)
sound
click-repeat-p
(mouse-up-handler nil :documentation "Menus use this")
(click-evt (c-in nil))
(double-click-evt (c-in nil))
(double-click-action (c-in nil))
(key-evt nil :cell :ephemeral)
(enabled t)
tool-tip
(kb-selector nil :cell nil))
(defmethod not-to-be :after ((self control))
(kb-manager-checkout self))
(defmethod do-double-click ((self control) )
(b-when a (^double-click-action)
(trc "control sees defmethod" self a)
(funcall a self)
t)) ;; ie, handled
(export! control-do-action)
(defmethod tool-tip-show? (other)
(declare (ignore other))
nil)
(defmethod tool-tip (other)
(declare (ignore other))
nil)
(defmacro ct-action-lambda (&body body)
`(lambda (self req)
(declare (ignorable self req))
,@body))
(defmethod kb-selector (other) (declare (ignore other)) nil)
(defmethod enabled (other)(assert other) nil)
(defmethod do-cello-keydown ((self control) k event)
(declare (ignorable event))
(when (control-triggered-by self k event)
(funcall (ct-action self) self event)
t)) ;; handled
; ----------------------------------------------------------
(defmethod do-cello-keydown :around (self key-char event)
(declare (ignorable key-char))
(typecase self
(null)
(window (ctl-notify-keydown self self key-char event)
(call-next-method))
(otherwise
(when (ctl-notify-keydown .parent self key-char event)
(unless (call-next-method)
(do-cello-keydown .parent key-char event))))))
(defmethod ctl-notify-keydown (self target key-char click)
(ctl-notify-keydown (fm-parent self) target key-char click))
(defmethod control-triggered-by (control k event)
(declare (ignorable event))
(eql k (kb-selector control))) ;; this is lame--to be enhanced
(defmethod ctl-disabled (other)
(declare (ignore other))
nil)
(defmethod ctl-disabled ((self control))
(not (enabled self)))
(export! fully-enabled)
(defmethod fully-enabled (self)
(declare (ignore self))
nil)
(defmethod fully-enabled ((self control))
"Test if self and all ascendant controls are enabled"
(labels ((no-disabled-up (node)
(unless (ctl-disabled node)
(bif (p (fm-parent node))
(no-disabled-up p)
t ;; reached top without hitting un-enabled control
))))
(no-disabled-up self)))
;
; /// m/b odd combo of customizable parameter 'controlAction and
; generic function 'control-do-action. we like instance-oriented
; programming, so keep 'controlAction, maybe just coordinate better
; by establishing a rule: call 'controlAction first, if supplied,
; and if it returns t that indicates "handled"? ugh
;
(defun control-do-action (ct trigger-evt &optional force)
(when (ct-action ct)
(if (or force (fully-enabled ct))
(progn
;(trc "Control-do-action calling" ct trigger-evt)
(clock :calling-ct-action)
(funcall (ct-action ct) ct trigger-evt)
(clock :called-ct-action)
;(trc "Control-do-action triggering FINIS" ct)
)
(when (enabled ct)
(trc "control enabled but neither forced nor fully enabled, so not acting" ct )))))
(export! control-trigger)
(defun control-trigger (self &key even-if-disabled)
;;(when (mdead self) (bgo wtf?))
(if (or even-if-disabled (^enabled))
(progn
(clock :control-trigger)
(control-do-action self nil even-if-disabled)
(clock :control-did-action))
(trc "not actually triggering disabled" self)))