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 ]