1 ## the 'copy' button makes it easy to duplicate a sandbox, and thence to
  2 ## see code operate in multiple situations
  3 
  4 scenario copy-a-sandbox-to-editor [
  5   local-scope
  6   trace-until 100/app  # trace too long
  7   assume-screen 100/width, 10/height
  8   # empty recipes
  9   assume-resources [
 10   ]
 11   env:&:environment <- new-programming-environment resources, screen, [add 1, 1]  # contents of sandbox editor
 12   # run it
 13   assume-console [
 14     press F4
 15   ]
 16   event-loop screen, console, env, resources
 17   screen-should-contain [
 18     .                                                                                 run (F4)           .
 19     .                                                  ╎                                                 .
 20     .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────.
 21     .                                                  ╎0   edit          copy            delete         .
 22     .                                                  ╎add 1, 1                                         .
 23     .                                                  ╎2                                                .
 24     .                                                  ╎─────────────────────────────────────────────────.
 25     .                                                  ╎                                                 .
 26   ]
 27   # click at left edge of 'copy' button
 28   assume-console [
 29     left-click 3, 69
 30   ]
 31   run [
 32     event-loop screen, console, env, resources
 33   ]
 34   # it copies into editor
 35   screen-should-contain [
 36     .                                                                                 run (F4)           .
 37     .                                                  ╎add 1, 1                                         .
 38     .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────.
 39     .                                                  ╎0   edit          copy            delete         .
 40     .                                                  ╎add 1, 1                                         .
 41     .                                                  ╎2                                                .
 42     .                                                  ╎─────────────────────────────────────────────────.
 43     .                                                  ╎                                                 .
 44   ]
 45   # cursor should be in the right place
 46   assume-console [
 47     type [0]
 48   ]
 49   run [
 50     event-loop screen, console, env, resources
 51   ]
 52   screen-should-contain [
 53     .                                                                                 run (F4)           .
 54     .                                                  ╎0add 1, 1                                        .
 55     .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────.
 56     .                                                  ╎0   edit          copy            delete         .
 57     .                                                  ╎add 1, 1                                         .
 58     .                                                  ╎2                                                .
 59     .                                                  ╎─────────────────────────────────────────────────.
 60     .                                                  ╎                                                 .
 61   ]
 62 ]
 63 
 64 scenario copy-a-sandbox-to-editor-2 [
 65   local-scope
 66   trace-until 100/app  # trace too long
 67   assume-screen 100/width, 10/height
 68   # empty recipes
 69   assume-resources [
 70   ]
 71   env:&:environment <- new-programming-environment resources, screen, [add 1, 1]  # contents of sandbox editor
 72   # run it
 73   assume-console [
 74     press F4
 75   ]
 76   event-loop screen, console, env, resources
 77   screen-should-contain [
 78     .                                                                                 run (F4)           .
 79     .                                                  ╎                                                 .
 80     .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────.
 81     .                                                  ╎0   edit          copy            delete         .
 82     .                                                  ╎add 1, 1                                         .
 83     .                                                  ╎2                                                .
 84     .                                                  ╎─────────────────────────────────────────────────.
 85     .                                                  ╎                                                 .
 86   ]
 87   # click at right edge of 'copy' button (just before 'delete')
 88   assume-console [
 89     left-click 3, 84
 90   ]
 91   run [
 92     event-loop screen, console, env, resources
 93   ]
 94   # it copies into editor
 95   screen-should-contain [
 96     .                                                                                 run (F4)           .
 97     .                                                  ╎add 1, 1                                         .
 98     .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────.
 99     .                                                  ╎0   edit          copy            delete         .
100     .                                                  ╎add 1, 1                                         .
101     .                                                  ╎2                                                .
102     .                                                  ╎─────────────────────────────────────────────────.
103     .                                                  ╎                                                 .
104   ]
105   # cursor should be in the right place
106   assume-console [
107     type [0]
108   ]
109   run [
110     event-loop screen, console, env, resources
111   ]
112   screen-should-contain [
113     .                                                                                 run (F4)           .
114     .                                                  ╎0add 1, 1                                        .
115     .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────.
116     .                                                  ╎0   edit          copy            delete         .
117     .                                                  ╎add 1, 1                                         .
118     .                                                  ╎2                                                .
119     .                                                  ╎─────────────────────────────────────────────────.
120     .                                                  ╎                                                 .
121   ]
122 ]
123 
124 after <global-touch> [
125   # support 'copy' button
126   {
127     copy?:bool <- should-attempt-copy? click-row, click-column, env
128     break-unless copy?
129     copy?, env <- try-copy-sandbox click-row, env
130     break-unless copy?
131     hide-screen screen
132     screen <- render-sandbox-side screen, env, render
133     screen <- update-cursor screen, recipes, current-sandbox, sandbox-in-focus?, env
134     show-screen screen
135     loop +next-event
136   }
137 ]
138 
139 # some preconditions for attempting to copy a sandbox
140 def should-attempt-copy? click-row:num, click-column:num, env:&:environment -> result:bool [
141   local-scope
142   load-ingredients
143   # are we below the sandbox editor?
144   click-sandbox-area?:bool <- click-on-sandbox-area? click-row, click-column, env
145   return-unless click-sandbox-area?, 0/false
146   # narrower, is the click in the columns spanning the 'copy' button?
147   first-sandbox:&:editor <- get *env, current-sandbox:offset
148   assert first-sandbox, [!!]
149   sandbox-left-margin:num <- get *first-sandbox, left:offset
150   sandbox-right-margin:num <- get *first-sandbox, right:offset
151   _, _, copy-button-left:num, copy-button-right:num, _ <- sandbox-menu-columns sandbox-left-margin, sandbox-right-margin
152   copy-button-vertical-area?:bool <- within-range? click-column, copy-button-left, copy-button-right
153   return-unless copy-button-vertical-area?, 0/false
154   # finally, is sandbox editor empty?
155   current-sandbox:&:editor <- get *env, current-sandbox:offset
156   result <- empty-editor? current-sandbox
157 ]
158 
159 def try-copy-sandbox click-row:num, env:&:environment -> clicked-on-copy-button?:bool, env:&:environment [
160   local-scope
161   load-ingredients
162   # identify the sandbox to copy, if the click was actually on the 'copy' button
163   sandbox:&:sandbox <- find-sandbox env, click-row
164   return-unless sandbox, 0/false
165   clicked-on-copy-button? <- copy 1/true
166   text:text <- get *sandbox, data:offset
167   current-sandbox:&:editor <- get *env, current-sandbox:offset
168   current-sandbox <- insert-text current-sandbox, text
169   # reset scroll
170   *env <- put *env, render-from:offset, -1
171   # position cursor in sandbox editor
172   *env <- put *env, sandbox-in-focus?:offset, 1/true
173 ]
174 
175 def find-sandbox env:&:environment, click-row:num -> result:&:sandbox [
176   local-scope
177   load-ingredients
178   curr-sandbox:&:sandbox <- get *env, sandbox:offset
179   {
180     break-unless curr-sandbox
181     start:num <- get *curr-sandbox, starting-row-on-screen:offset
182     found?:bool <- equal click-row, start
183     return-if found?, curr-sandbox
184     curr-sandbox <- get *curr-sandbox, next-sandbox:offset
185     loop
186   }
187   return 0/not-found
188 ]
189 
190 def click-on-sandbox-area? click-row:num, click-column:num, env:&:environment -> result:bool [
191   local-scope
192   load-ingredients
193   current-sandbox:&:editor <- get *env, current-sandbox:offset
194   sandbox-left-margin:num <- get *current-sandbox, left:offset
195   on-sandbox-side?:bool <- greater-or-equal click-column, sandbox-left-margin
196   return-unless on-sandbox-side?, 0/false
197   first-sandbox:&:sandbox <- get *env, sandbox:offset
198   return-unless first-sandbox, 0/false
199   first-sandbox-begins:num <- get *first-sandbox, starting-row-on-screen:offset
200   result <- greater-or-equal click-row, first-sandbox-begins
201 ]
202 
203 def empty-editor? editor:&:editor -> result:bool [
204   local-scope
205   load-ingredients
206   head:&:duplex-list:char <- get *editor, data:offset
207   first:&:duplex-list:char <- next head
208   result <- not first
209 ]
210 
211 def within-range? x:num, low:num, high:num -> result:bool [
212   local-scope
213   load-ingredients
214   not-too-far-left?:bool <- greater-or-equal x, low
215   not-too-far-right?:bool <- lesser-or-equal x, high
216   result <- and not-too-far-left? not-too-far-right?
217 ]
218 
219 scenario copy-fails-if-sandbox-editor-not-empty [
220   local-scope
221   trace-until 100/app  # trace too long
222   assume-screen 100/width, 10/height
223   # empty recipes
224   assume-resources [
225   ]
226   env:&:environment <- new-programming-environment resources, screen, [add 1, 1]  # contents of sandbox editor
227   # run it
228   assume-console [
229     press F4
230   ]
231   event-loop screen, console, env, resources
232   screen-should-contain [
233     .                                                                                 run (F4)           .
234     .                                                  ╎                                                 .
235     .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────.
236     .                                                  ╎0   edit          copy            delete         .
237     .                                                  ╎add 1, 1                                         .
238     .                                                  ╎2                                                .
239     .                                                  ╎─────────────────────────────────────────────────.
240     .                                                  ╎                                                 .
241   ]
242   # type something into the sandbox editor, then click on the 'copy' button
243   assume-console [
244     left-click 2, 70  # put cursor in sandbox editor
245     type [0]  # type something
246     left-click 3, 70  # click 'copy' button
247   ]
248   run [
249     event-loop screen, console, env, resources
250   ]
251   # copy doesn't happen
252   screen-should-contain [
253     .                                                                                 run (F4)           .
254     .                                                  ╎0                                                .
255     .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────.
256     .                                                  ╎0   edit          copy            delete         .
257     .                                                  ╎add 1, 1                                         .
258     .                                                  ╎2                                                .
259     .                                                  ╎─────────────────────────────────────────────────.
260     .                                                  ╎                                                 .
261   ]
262   # cursor should be in the right place
263   assume-console [
264     type [1]
265   ]
266   run [
267     event-loop screen, console, env, resources
268   ]
269   screen-should-contain [
270     .                                                                                 run (F4)           .
271     .                                                  ╎01                                               .
272     .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────.
273     .                                                  ╎0   edit          copy            delete         .
274     .                                                  ╎add 1, 1                                         .
275     .                                                  ╎2                                                .
276     .                                                  ╎─────────────────────────────────────────────────.
277     .                                                  ╎                                                 .
278   ]
279 ]