diff options
-rw-r--r-- | 051recipe_header.cc | 10 | ||||
-rw-r--r-- | edit/004-programming-environment.mu | 2 | ||||
-rw-r--r-- | edit/006-sandbox-copy.mu | 284 | ||||
-rw-r--r-- | edit/007-sandbox-delete.mu | 97 | ||||
-rw-r--r-- | edit/008-sandbox-edit.mu | 109 |
5 files changed, 379 insertions, 123 deletions
diff --git a/051recipe_header.cc b/051recipe_header.cc index 29787fae..c58962a0 100644 --- a/051recipe_header.cc +++ b/051recipe_header.cc @@ -336,10 +336,12 @@ void deduce_types_from_header(const recipe_ordinal r) { trace(9991, "transform") << "--- deduce types from header for " << caller_recipe.name << end(); map<string, const type_tree*> header_type; for (int i = 0; i < SIZE(caller_recipe.ingredients); ++i) { + if (!caller_recipe.ingredients.at(i).type) continue; // error handled elsewhere put(header_type, caller_recipe.ingredients.at(i).name, caller_recipe.ingredients.at(i).type); trace(9993, "transform") << "type of " << caller_recipe.ingredients.at(i).name << " is " << names_to_string(caller_recipe.ingredients.at(i).type) << end(); } for (int i = 0; i < SIZE(caller_recipe.products); ++i) { + if (!caller_recipe.products.at(i).type) continue; // error handled elsewhere put(header_type, caller_recipe.products.at(i).name, caller_recipe.products.at(i).type); trace(9993, "transform") << "type of " << caller_recipe.products.at(i).name << " is " << names_to_string(caller_recipe.products.at(i).type) << end(); } @@ -350,8 +352,8 @@ void deduce_types_from_header(const recipe_ordinal r) { if (inst.ingredients.at(i).type) continue; if (header_type.find(inst.ingredients.at(i).name) == header_type.end()) continue; - if (!inst.ingredients.at(i).type) - inst.ingredients.at(i).type = new type_tree(*get(header_type, inst.ingredients.at(i).name)); + if (!contains_key(header_type, inst.ingredients.at(i).name)) continue; // error handled elsewhere + inst.ingredients.at(i).type = new type_tree(*get(header_type, inst.ingredients.at(i).name)); trace(9993, "transform") << "type of " << inst.ingredients.at(i).name << " is " << names_to_string(inst.ingredients.at(i).type) << end(); } for (int i = 0; i < SIZE(inst.products); ++i) { @@ -359,8 +361,8 @@ void deduce_types_from_header(const recipe_ordinal r) { if (inst.products.at(i).type) continue; if (header_type.find(inst.products.at(i).name) == header_type.end()) continue; - if (!inst.products.at(i).type) - inst.products.at(i).type = new type_tree(*get(header_type, inst.products.at(i).name)); + if (!contains_key(header_type, inst.products.at(i).name)) continue; // error handled elsewhere + inst.products.at(i).type = new type_tree(*get(header_type, inst.products.at(i).name)); trace(9993, "transform") << "type of " << inst.products.at(i).name << " is " << names_to_string(inst.products.at(i).type) << end(); } } diff --git a/edit/004-programming-environment.mu b/edit/004-programming-environment.mu index a432d565..99584c56 100644 --- a/edit/004-programming-environment.mu +++ b/edit/004-programming-environment.mu @@ -86,6 +86,8 @@ def event-loop screen:address:screen, console:address:console, env:address:progr touch-type:number <- get t, type:offset is-left-click?:boolean <- equal touch-type, 65513/mouse-left loop-unless is-left-click?, +next-event:label + click-row:number <- get t, row:offset + click-column:number <- get t, column:offset # later exceptions for non-editor touches will go here <global-touch> # send to both editors diff --git a/edit/006-sandbox-copy.mu b/edit/006-sandbox-copy.mu new file mode 100644 index 00000000..867be5ff --- /dev/null +++ b/edit/006-sandbox-copy.mu @@ -0,0 +1,284 @@ +## the 'copy' button makes it easy to duplicate a sandbox, and thence to +## see code operate in multiple situations + +scenario copy-a-sandbox-to-editor [ + trace-until 100/app # trace too long + assume-screen 100/width, 10/height + # basic recipe + 1:address:array:character <- new [ +recipe foo [ + reply 4 +]] + # run it + 2:address:array:character <- new [foo] + assume-console [ + press F4 + ] + 3:address:programming-environment-data <- new-programming-environment screen:address:screen, 1:address:array:character, 2:address:array:character + event-loop screen:address:screen, console:address:console, 3:address:programming-environment-data + screen-should-contain [ + . run (F4) . + . ┊ . + .recipe foo [ ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━. + . reply 4 ┊0 edit copy delete . + .] ┊foo . + .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊4 . + . ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━. + . ┊ . + ] + # click at left edge of 'copy' button + assume-console [ + left-click 3, 69 + ] + run [ + event-loop screen:address:screen, console:address:console, 3:address:programming-environment-data + ] + # it copies into editor + screen-should-contain [ + . run (F4) . + . ┊foo . + .recipe foo [ ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━. + . reply 4 ┊0 edit copy delete . + .] ┊foo . + .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊4 . + . ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━. + . ┊ . + ] + # cursor should be in the right place + assume-console [ + type [0] + ] + run [ + event-loop screen:address:screen, console:address:console, 3:address:programming-environment-data + ] + screen-should-contain [ + . run (F4) . + . ┊0foo . + .recipe foo [ ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━. + . reply 4 ┊0 edit copy delete . + .] ┊foo . + .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊4 . + . ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━. + . ┊ . + ] +] + +scenario copy-a-sandbox-to-editor-2 [ + trace-until 100/app # trace too long + assume-screen 100/width, 10/height + # basic recipe + 1:address:array:character <- new [ +recipe foo [ + reply 4 +]] + # run it + 2:address:array:character <- new [foo] + assume-console [ + press F4 + ] + 3:address:programming-environment-data <- new-programming-environment screen:address:screen, 1:address:array:character, 2:address:array:character + event-loop screen:address:screen, console:address:console, 3:address:programming-environment-data + screen-should-contain [ + . run (F4) . + . ┊ . + .recipe foo [ ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━. + . reply 4 ┊0 edit copy delete . + .] ┊foo . + .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊4 . + . ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━. + . ┊ . + ] + # click at right edge of 'copy' button (just before 'delete') + assume-console [ + left-click 3, 84 + ] + run [ + event-loop screen:address:screen, console:address:console, 3:address:programming-environment-data + ] + # it copies into editor + screen-should-contain [ + . run (F4) . + . ┊foo . + .recipe foo [ ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━. + . reply 4 ┊0 edit copy delete . + .] ┊foo . + .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊4 . + . ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━. + . ┊ . + ] + # cursor should be in the right place + assume-console [ + type [0] + ] + run [ + event-loop screen:address:screen, console:address:console, 3:address:programming-environment-data + ] + screen-should-contain [ + . run (F4) . + . ┊0foo . + .recipe foo [ ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━. + . reply 4 ┊0 edit copy delete . + .] ┊foo . + .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊4 . + . ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━. + . ┊ . + ] +] + +after <global-touch> [ + # support 'copy' button + { + copy?:boolean <- should-attempt-copy? click-row, click-column, env + break-unless copy? + copy?, env <- try-copy-sandbox click-row, env + break-unless copy? + hide-screen screen + screen <- render-sandbox-side screen, env + screen <- update-cursor screen, recipes, current-sandbox, sandbox-in-focus?, env + show-screen screen + loop +next-event:label + } +] + +# some preconditions for attempting to copy a sandbox +def should-attempt-copy? click-row:number, click-column:number, env:address:programming-environment-data -> result:boolean [ + local-scope + load-ingredients + # are we below the sandbox editor? + click-sandbox-area?:boolean <- click-on-sandbox-area? click-row, click-column, env + reply-unless click-sandbox-area?, 0/false + # narrower, is the click in the columns spanning the 'copy' button? + first-sandbox:address:editor-data <- get *env, current-sandbox:offset + assert first-sandbox, [!!] + sandbox-left-margin:number <- get *first-sandbox, left:offset + sandbox-right-margin:number <- get *first-sandbox, right:offset + _, _, copy-button-left:number, copy-button-right:number, _ <- sandbox-menu-columns sandbox-left-margin, sandbox-right-margin + copy-button-vertical-area?:boolean <- within-range? click-column, copy-button-left, copy-button-right + reply-unless copy-button-vertical-area?, 0/false + # finally, is sandbox editor empty? + current-sandbox:address:editor-data <- get *env, current-sandbox:offset + result <- empty-editor? current-sandbox +] + +def try-copy-sandbox click-row:number, env:address:programming-environment-data -> clicked-on-copy-button?:boolean, env:address:programming-environment-data [ + local-scope + load-ingredients + # identify the sandbox to copy, if the click was actually on the 'copy' button + sandbox:address:sandbox-data <- find-sandbox env, click-row + return-unless sandbox, 0/false + clicked-on-copy-button? <- copy 1/true + text:address:array:character <- get *sandbox, data:offset + current-sandbox:address:editor-data <- get *env, current-sandbox:offset + current-sandbox <- insert-text current-sandbox, text + # reset scroll + *env <- put *env, render-from:offset, -1 + # position cursor in sandbox editor + *env <- put *env, sandbox-in-focus?:offset, 1/true +] + +def find-sandbox env:address:programming-environment-data, click-row:number -> result:address:sandbox-data [ + local-scope + load-ingredients + curr-sandbox:address:sandbox-data <- get *env, sandbox:offset + { + start:number <- get *curr-sandbox, starting-row-on-screen:offset + found?:boolean <- equal click-row, start + return-if found?, curr-sandbox + curr-sandbox <- get *curr-sandbox, next-sandbox:offset + loop + } + return 0/not-found +] + +def click-on-sandbox-area? click-row:number, click-column:number, env:address:programming-environment-data -> result:boolean [ + local-scope + load-ingredients + current-sandbox:address:editor-data <- get *env, current-sandbox:offset + sandbox-left-margin:number <- get *current-sandbox, left:offset + on-sandbox-side?:boolean <- greater-or-equal click-column, sandbox-left-margin + return-unless on-sandbox-side?, 0/false + first-sandbox:address:sandbox-data <- get *env, sandbox:offset + return-unless first-sandbox, 0/false + first-sandbox-begins:number <- get *first-sandbox, starting-row-on-screen:offset + result <- greater-or-equal click-row, first-sandbox-begins +] + +def empty-editor? editor:address:editor-data -> result:boolean [ + local-scope + load-ingredients + head:address:duplex-list:character <- get *editor, data:offset + first:address:duplex-list:character <- next head + result <- not first +] + +def within-range? x:number, low:number, high:number -> result:boolean [ + local-scope + load-ingredients + not-too-far-left?:boolean <- greater-or-equal x, low + not-too-far-right?:boolean <- lesser-or-equal x, high + result <- and not-too-far-left? not-too-far-right? +] + +scenario copy-fails-if-sandbox-editor-not-empty [ + trace-until 100/app # trace too long + assume-screen 100/width, 10/height + # basic recipe + 1:address:array:character <- new [ +recipe foo [ + reply 4 +]] + # run it + 2:address:array:character <- new [foo] + assume-console [ + press F4 + ] + 3:address:programming-environment-data <- new-programming-environment screen:address:screen, 1:address:array:character, 2:address:array:character + event-loop screen:address:screen, console:address:console, 3:address:programming-environment-data + screen-should-contain [ + . run (F4) . + . ┊ . + .recipe foo [ ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━. + . reply 4 ┊0 edit copy delete . + .] ┊foo . + .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊4 . + . ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━. + . ┊ . + ] + # type something into the sandbox editor, then click on the 'copy' button + assume-console [ + left-click 2, 70 # put cursor in sandbox editor + type [0] # type something + left-click 3, 70 # click 'copy' button + ] + run [ + event-loop screen:address:screen, console:address:console, 3:address:programming-environment-data + ] + # copy doesn't happen + screen-should-contain [ + . run (F4) . + . ┊0 . + .recipe foo [ ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━. + . reply 4 ┊0 edit copy delete . + .] ┊foo . + .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊4 . + . ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━. + . ┊ . + ] + # cursor should be in the right place + assume-console [ + type [1] + ] + run [ + event-loop screen:address:screen, console:address:console, 3:address:programming-environment-data + ] + screen-should-contain [ + . run (F4) . + . ┊01 . + .recipe foo [ ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━. + . reply 4 ┊0 edit copy delete . + .] ┊foo . + .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊4 . + . ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━. + . ┊ . + ] +] diff --git a/edit/007-sandbox-delete.mu b/edit/007-sandbox-delete.mu index c915dc75..6e377e38 100644 --- a/edit/007-sandbox-delete.mu +++ b/edit/007-sandbox-delete.mu @@ -65,10 +65,12 @@ scenario deleting-sandboxes [ ] after <global-touch> [ - # on a sandbox delete icon? process delete + # support 'delete' button { - was-delete?:boolean <- try-delete-sandbox t, env - break-unless was-delete? + delete?:boolean <- should-attempt-delete? click-row, click-column, env + break-unless delete? + delete?, env <- try-delete-sandbox click-row, env + break-unless delete? hide-screen screen screen <- render-sandbox-side screen, env screen <- update-cursor screen, recipes, current-sandbox, sandbox-in-focus?, env @@ -77,63 +79,70 @@ after <global-touch> [ } ] -def try-delete-sandbox t:touch-event, env:address:programming-environment-data -> was-delete?:boolean, env:address:programming-environment-data [ +# some preconditions for attempting to delete a sandbox +def should-attempt-delete? click-row:number, click-column:number, env:address:programming-environment-data -> result:boolean [ local-scope load-ingredients - click-column:number <- get t, column:offset - current-sandbox:address:editor-data <- get *env, current-sandbox:offset - right:number <- get *current-sandbox, right:offset - at-right?:boolean <- equal click-column, right - return-unless at-right?, 0/false - click-row:number <- get t, row:offset + # are we below the sandbox editor? + click-sandbox-area?:boolean <- click-on-sandbox-area? click-row, click-column, env + reply-unless click-sandbox-area?, 0/false + # narrower, is the click in the columns spanning the 'copy' button? + first-sandbox:address:editor-data <- get *env, current-sandbox:offset + assert first-sandbox, [!!] + sandbox-left-margin:number <- get *first-sandbox, left:offset + sandbox-right-margin:number <- get *first-sandbox, right:offset + _, _, _, _, delete-button-left:number <- sandbox-menu-columns sandbox-left-margin, sandbox-right-margin + result <- within-range? click-column, delete-button-left, sandbox-right-margin +] + +def try-delete-sandbox click-row:number, env:address:programming-environment-data -> clicked-on-delete-button?:boolean, env:address:programming-environment-data [ + local-scope + load-ingredients + # identify the sandbox to delete, if the click was actually on the 'delete' button + sandbox:address:sandbox-data <- find-sandbox env, click-row + return-unless sandbox, 0/false + clicked-on-delete-button? <- copy 1/true + env <- delete-sandbox env, sandbox +] + +def delete-sandbox env:address:programming-environment-data, sandbox:address:sandbox-data -> env:address:programming-environment-data [ + local-scope + load-ingredients + curr-sandbox:address:sandbox-data <- get *env, sandbox:offset + first-sandbox?:boolean <- equal curr-sandbox, sandbox { - first:address:sandbox-data <- get *env, sandbox:offset - reply-unless first, 0/false - target-row:number <- get *first, starting-row-on-screen:offset - delete-first?:boolean <- equal target-row, click-row - break-unless delete-first? - new-first:address:sandbox-data <- get *first, next-sandbox:offset - *env <- put *env, sandbox:offset, new-first - env <- fixup-delete env, new-first - return 1/true # force rerender + # first sandbox? pop + break-unless first-sandbox? + next-sandbox:address:sandbox-data <- get *curr-sandbox, next-sandbox:offset + *env <- put *env, sandbox:offset, next-sandbox } - prev:address:sandbox-data <- get *env, sandbox:offset - assert prev, [failed to find any sandboxes!] - curr:address:sandbox-data <- get *prev, next-sandbox:offset { - break-unless curr - # more sandboxes to check + # not first sandbox? + break-if first-sandbox? + prev-sandbox:address:sandbox-data <- copy curr-sandbox + curr-sandbox <- get *curr-sandbox, next-sandbox:offset { - target-row:number <- get *curr, starting-row-on-screen:offset - delete-curr?:boolean <- equal target-row, click-row - break-unless delete-curr? - # delete this sandbox - next:address:sandbox-data <- get *curr, next-sandbox:offset - *prev <- put *prev, next-sandbox:offset, next - env <- fixup-delete env, next - return 1/true # force rerender + assert curr-sandbox, [sandbox not found! something is wrong.] + found?:boolean <- equal curr-sandbox, sandbox + break-if found? + prev-sandbox <- copy curr-sandbox + curr-sandbox <- get *curr-sandbox, next-sandbox:offset + loop } - prev <- copy curr - curr <- get *curr, next-sandbox:offset - loop + # snip sandbox out of its list + next-sandbox:address:sandbox-data <- get *curr-sandbox, next-sandbox:offset + *prev-sandbox <- put *prev-sandbox, next-sandbox:offset, next-sandbox } - return 0/false -] - -def fixup-delete env:address:programming-environment-data, next:address:sandbox-data -> env:address:programming-environment-data [ - local-scope - load-ingredients # update sandbox count sandbox-count:number <- get *env, number-of-sandboxes:offset sandbox-count <- subtract sandbox-count, 1 *env <- put *env, number-of-sandboxes:offset, sandbox-count + # reset scroll if deleted sandbox was last { - break-if next - # deleted sandbox was last + break-if next-sandbox render-from:number <- get *env, render-from:offset reset-scroll?:boolean <- equal render-from, sandbox-count break-unless reset-scroll? - # deleted sandbox was only sandbox rendered, so reset scroll *env <- put *env, render-from:offset, -1 } ] diff --git a/edit/008-sandbox-edit.mu b/edit/008-sandbox-edit.mu index edea112d..df897a6e 100644 --- a/edit/008-sandbox-edit.mu +++ b/edit/008-sandbox-edit.mu @@ -25,7 +25,7 @@ recipe foo [ . ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━. . ┊ . ] - # click at left edge of edit button + # click at left edge of 'edit' button assume-console [ left-click 3, 55 ] @@ -85,7 +85,7 @@ recipe foo [ . ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━. . ┊ . ] - # click at right edge of edit button (just before 'copy') + # click at right edge of 'edit' button (just before 'copy') assume-console [ left-click 3, 68 ] @@ -121,10 +121,12 @@ recipe foo [ ] after <global-touch> [ - # below sandbox editor? pop appropriate sandbox contents back into sandbox editor + # support 'edit' button { - was-edit?:boolean <- try-edit-sandbox t, env - break-unless was-edit? + edit?:boolean <- should-attempt-edit? click-row, click-column, env + break-unless edit? + edit?, env <- try-edit-sandbox click-row, env + break-unless edit? hide-screen screen screen <- render-sandbox-side screen, env screen <- update-cursor screen, recipes, current-sandbox, sandbox-in-focus?, env @@ -133,83 +135,40 @@ after <global-touch> [ } ] -def try-edit-sandbox t:touch-event, env:address:programming-environment-data -> was-edit?:boolean, env:address:programming-environment-data [ +# some preconditions for attempting to edit a sandbox +def should-attempt-edit? click-row:number, click-column:number, env:address:programming-environment-data -> result:boolean [ local-scope load-ingredients - click-column:number <- get t, column:offset - current-sandbox:address:editor-data <- get *env, current-sandbox:offset - sandbox-left-margin:number <- get *current-sandbox, left:offset - on-sandbox-side?:boolean <- greater-or-equal click-column, sandbox-left-margin - return-unless on-sandbox-side?, 0/false - first-sandbox:address:sandbox-data <- get *env, sandbox:offset - return-unless first-sandbox, 0/false - first-sandbox-begins:number <- get *first-sandbox, starting-row-on-screen:offset - click-row:number <- get t, row:offset - below-sandbox-editor?:boolean <- greater-or-equal click-row, first-sandbox-begins - return-unless below-sandbox-editor?, 0/false - empty-sandbox-editor?:boolean <- empty-editor? current-sandbox - return-unless empty-sandbox-editor?, 0/false # don't clobber existing contents - sandbox-right-margin:number <- get *current-sandbox, right:offset + # are we below the sandbox editor? + click-sandbox-area?:boolean <- click-on-sandbox-area? click-row, click-column, env + reply-unless click-sandbox-area?, 0/false + # narrower, is the click in the columns spanning the 'edit' button? + first-sandbox:address:editor-data <- get *env, current-sandbox:offset + assert first-sandbox, [!!] + sandbox-left-margin:number <- get *first-sandbox, left:offset + sandbox-right-margin:number <- get *first-sandbox, right:offset edit-button-left:number, edit-button-right:number, _ <- sandbox-menu-columns sandbox-left-margin, sandbox-right-margin - left-of-edit-button?:boolean <- lesser-than click-column, edit-button-left - return-if left-of-edit-button?, 0/false - right-of-edit-button?:boolean <- greater-than click-column, edit-button-right - return-if right-of-edit-button?, 0/false - # identify the sandbox to edit and remove it from the sandbox list - sandbox:address:sandbox-data <- extract-sandbox env, click-row - return-unless sandbox, 0/false - text:address:array:character <- get *sandbox, data:offset - current-sandbox <- insert-text current-sandbox, text - *env <- put *env, render-from:offset, -1 - return 1/true -] - -def empty-editor? editor:address:editor-data -> result:boolean [ - local-scope - load-ingredients - head:address:duplex-list:character <- get *editor, data:offset - first:address:duplex-list:character <- next head - result <- not first + edit-button-vertical-area?:boolean <- within-range? click-column, edit-button-left, edit-button-right + reply-unless edit-button-vertical-area?, 0/false + # finally, is sandbox editor empty? + current-sandbox:address:editor-data <- get *env, current-sandbox:offset + result <- empty-editor? current-sandbox ] -def extract-sandbox env:address:programming-environment-data, click-row:number -> result:address:sandbox-data, env:address:programming-environment-data [ +def try-edit-sandbox click-row:number, env:address:programming-environment-data -> clicked-on-edit-button?:boolean, env:address:programming-environment-data [ local-scope load-ingredients - curr-sandbox:address:sandbox-data <- get *env, sandbox:offset - start:number <- get *curr-sandbox, starting-row-on-screen:offset - in-editor?:boolean <- lesser-than click-row, start - return-if in-editor?, 0 - first-sandbox?:boolean <- equal click-row, start - { - # first sandbox? pop - break-unless first-sandbox? - next-sandbox:address:sandbox-data <- get *curr-sandbox, next-sandbox:offset - *env <- put *env, sandbox:offset, next-sandbox - } - { - # not first sandbox? - break-if first-sandbox? - prev-sandbox:address:sandbox-data <- copy curr-sandbox - curr-sandbox <- get *curr-sandbox, next-sandbox:offset - { - next-sandbox:address:sandbox-data <- get *curr-sandbox, next-sandbox:offset - break-unless next-sandbox - # if click-row < sandbox.next-sandbox.starting-row-on-screen, break - next-start:number <- get *next-sandbox, starting-row-on-screen:offset - found?:boolean <- lesser-than click-row, next-start - break-if found? - prev-sandbox <- copy curr-sandbox - curr-sandbox <- copy next-sandbox - loop - } - # snip sandbox out of its list - *prev-sandbox <- put *prev-sandbox, next-sandbox:offset, next-sandbox - } - result <- copy curr-sandbox - # update sandbox count - sandbox-count:number <- get *env, number-of-sandboxes:offset - sandbox-count <- subtract sandbox-count, 1 - *env <- put *env, number-of-sandboxes:offset, sandbox-count + # identify the sandbox to edit, if the click was actually on the 'edit' button + sandbox:address:sandbox-data <- find-sandbox env, click-row + return-unless sandbox, 0/false + clicked-on-edit-button? <- copy 1/true + # 'edit' button = 'copy' button + 'delete' button + text:address:array:character <- get *sandbox, data:offset + current-sandbox:address:editor-data <- get *env, current-sandbox:offset + current-sandbox <- insert-text current-sandbox, text + env <- delete-sandbox env, sandbox + # reset scroll + *env <- put *env, render-from:offset, -1 # position cursor in sandbox editor *env <- put *env, sandbox-in-focus?:offset, 1/true ] |