diff --git a/dist/plugins/iwsy.js b/dist/plugins/iwsy.js index c707623..e8ee213 100644 --- a/dist/plugins/iwsy.js +++ b/dist/plugins/iwsy.js @@ -11,16 +11,46 @@ const EasyCoder_IWSY = { const lino = compiler.getLino(); const action = compiler.nextToken(); - if ([`init`, `show`].includes(action)) { - compiler.next(); - compiler.addCommand({ - domain: `iwsy`, - keyword: `iwsy`, - lino, - action - }); - return true; - } + switch (action) { + case `load`: + if (compiler.nextIsSymbol()) { + const playerRecord = compiler.getSymbolRecord(); + if (playerRecord.keyword === `div`) { + const script = compiler.getNextValue(); + compiler.addCommand({ + domain: `iwsy`, + keyword: `iwsy`, + lino, + action, + player: playerRecord.name, + script + }); + return true; + } + } + break; + case `init`: + compiler.next(); + compiler.addCommand({ + domain: `iwsy`, + keyword: `iwsy`, + lino, + action + }); + return true; + case `goto`: + const target = compiler.getNextValue(); + compiler.addCommand({ + domain: `iwsy`, + keyword: `iwsy`, + lino, + action, + target + }); + return true; + default: + break; + } return false; }, @@ -33,8 +63,18 @@ const EasyCoder_IWSY = { function () { program.run(command.pc + 1); }); + return 0; + case `load`: + const playerRecord = program.getSymbolRecord(command.player); + const player = playerRecord.element[playerRecord.index]; + player.innerHTML = ``; + player.style.background = `none`; + player.style.border = `none`; + const script = program.getValue(command.script); + EasyCoder.iwsyGotoStep = IWSY(player, JSON.parse(script)); break; - case `show`: + case `goto`: + EasyCoder.iwsyGotoStep(program.getValue(command.target)); break; } return command.pc + 1; diff --git a/iwsy/iwsy.js b/iwsy/iwsy.js index 11393c3..2f914a4 100644 --- a/iwsy/iwsy.js +++ b/iwsy/iwsy.js @@ -105,38 +105,40 @@ const IWSY = (container, script) => { block.element = element; element.style[`position`] = `absolute`; element.style[`opacity`] = `0.0`; - let val = properties.blockLeft; + let val = properties.left; if (!isNaN(val)) { val *= w; } element.style[`left`] = val; - val = properties.blockTop; + val = properties.top; if (!isNaN(val)) { val *= h; } element.style[`top`] = val; - val = properties.blockWidth; + val = properties.width; if (!isNaN(val)) { - val *= w; + val = `${val * w}px`; } - element.style[`width`] = `${val}px`; - val = properties.blockHeight; + element.style[`width`] = val; + val = properties.height; if (!isNaN(val)) { - val *= h; + val = `${val * h}px`; } - element.style[`height`] = `${val}px`; - element.style[`background`] = properties.blockBackground; - element.style[`border`] = properties.blockBorder; + element.style[`height`] = val; + element.style[`background`] = properties.background; + element.style[`border`] = properties.border; container.appendChild(element); val = properties.textMarginLeft; if (!isNaN(val)) { - val *= w; + val = `${val * w}px`; } + element.style[`width`] = val; const marginLeft = val; val = properties.textMarginTop; if (!isNaN(val)) { - val *= h; + val = `${val * h}px`; } + element.style[`height`] = val; const marginTop = val; const inner = document.createElement(`div`); inner.style[`position`] = `absolute`; @@ -176,30 +178,30 @@ const IWSY = (container, script) => { block.element = element; element.style[`position`] = `absolute`; element.style[`opacity`] = `0.0`; - let val = properties.blockLeft; + let val = properties.left; if (!isNaN(val)) { val *= w; } element.style[`left`] = val; - val = properties.blockTop; + val = properties.top; if (!isNaN(val)) { val *= h; } element.style[`top`] = val; element.style[`top`] = val; - val = properties.blockWidth; + val = properties.width; if (!isNaN(val)) { - val *= w; + val = `${val * w}px`; } - element.style[`width`] = `${val}px`; - val = properties.blockHeight; + element.style[`width`] = val; + val = properties.height; if (!isNaN(val)) { - val *= h; + val = `${val * h}px`; } - element.style[`height`] = `${val}px`; - element.style[`background`] = properties.blockBackground; - element.style[`border`] = properties.blockBorder; - element.style[`border-radius`] = properties.blockBorderRadius; + element.style[`height`] = val; + element.style[`background`] = properties.background; + element.style[`border`] = properties.border; + element.style[`border-radius`] = properties.borderRadius; container.appendChild(element); if (script.speed === `scan`) { element.style.opacity = 0; @@ -634,6 +636,13 @@ const IWSY = (container, script) => { } }; + // Go to a specified step number + const gotoStep = (target) => { + script.scanTarget = target; + script.singleStep = true; + scan(); + }; + // Load a plugin action const load = step => { if (script.speed === `scan`) { @@ -652,7 +661,7 @@ const IWSY = (container, script) => { } }; - // Initialize the presenttion + // Initialize the presentation const init = step => { if (step.title) { document.title = step.title; @@ -677,6 +686,16 @@ const IWSY = (container, script) => { step.next(); }; + // Chain to another presentation + const chain = step => { + step.next() + }; + + // Embed another presentation + const embed = step => { + step.next() + }; + const actions = { init, setcontent, @@ -689,7 +708,9 @@ const IWSY = (container, script) => { crossfade, transition, goto, - load + load, + chain, + embed }; // Process a single step @@ -722,104 +743,48 @@ const IWSY = (container, script) => { handler(step); }; - // Initialization - const setup = () => { - container.innerHTML = ``; - document.removeEventListener(`click`, init); - if (mode === `auto`) { - document.addEventListener(`click`, onClick); - } - document.onkeydown = null; - script.container = container; - container.style.position = `relative`; - container.style.overflow = `hidden`; - container.style.cursor = 'none'; - container.style[`background-size`] = `cover`; - script.speed = `normal`; - script.labels = {}; - for (const [index, step] of script.steps.entries()) { - step.index = index; - step.script = script; - if (typeof step.label !== `undefined`) { - script.labels[step.label] = index; - } - if (index < script.steps.length - 1) { - step.next = () => { + container.innerHTML = ``; + document.removeEventListener(`click`, init); + if (mode === `auto`) { + document.addEventListener(`click`, onClick); + } + document.onkeydown = null; + script.container = container; + container.style.position = `relative`; + container.style.overflow = `hidden`; + container.style.cursor = 'none'; + container.style[`background-size`] = `cover`; + script.speed = `normal`; + script.singleStep = true; + script.labels = {}; + for (const [index, step] of script.steps.entries()) { + step.index = index; + step.script = script; + if (typeof step.label !== `undefined`) { + script.labels[step.label] = index; + } + if (index < script.steps.length - 1) { + step.next = () => { + if (script.singleStep && script.speed != `scan`) { + console.log(`Single-step`); + } else { const next = step.index + 1; setTimeout(() => { doStep(script.steps[next]); }, 0); } } - else { - step.next = () => { - console.log(`Step ${index + 1}: Finished`); - container.style.cursor = 'pointer'; - } - }; - } - IWSY.plugins = {}; - initBlocks(); - preloadImages(); - doStep(script.steps[0]); - }; - - // Wait for a click/tap or a keypress to start - document.addEventListener(`click`, init); - document.onkeydown = function (event) { - if (event.code === `Enter`) { - mode = `auto`; - } - setup(); - return true; - }; -}; - -window.onload = () => { - const createCORSRequest = (url) => { - let xhr = new XMLHttpRequest(); - if (`withCredentials` in xhr) { - - // Check if the XMLHttpRequest object has a "withCredentials" property. - // "withCredentials" only exists on XMLHTTPRequest2 objects. - xhr.open(`GET`, url, true); - - } else if (typeof XDomainRequest != `undefined`) { - - // Otherwise, check if XDomainRequest. - // XDomainRequest only exists in IE, and is IE's way of making CORS requests. - xhr = new XDomainRequest(); - xhr.open(`GET`, url); - - } else { - - // Otherwise, CORS is not supported by the browser. - xhr = null; - } - return xhr; - }; - - const scriptElement = document.getElementById(`iwsy-script`); - if (scriptElement) { - const request = createCORSRequest(`${scriptElement.innerText}?v=${Math.floor(Date.now())}`); - if (!request) { - throw Error(`Unable to access the JSON script`); - } - - request.onload = () => { - if (200 <= request.status && request.status < 400) { - const script = JSON.parse(request.responseText); - IWSY(document.getElementById(`iwsy-container`), script); - } else { - throw Error(`Unable to access the JSON script`); + else { + step.next = () => { + console.log(`Step ${index + 1}: Finished`); + container.style.cursor = 'pointer'; } }; - - request.onerror = () => { - throw Error(`Unable to access the JSON script`); - }; - - request.send(); } + IWSY.plugins = {}; + initBlocks(); + preloadImages(); + doStep(script.steps[0]); + return gotoStep; }; diff --git a/iwsy/iwsystart.js b/iwsy/iwsystart.js new file mode 100644 index 0000000..2f8cb31 --- /dev/null +++ b/iwsy/iwsystart.js @@ -0,0 +1,58 @@ +window.onload = () => { + const createCORSRequest = (url) => { + let xhr = new XMLHttpRequest(); + if (`withCredentials` in xhr) { + + // Check if the XMLHttpRequest object has a "withCredentials" property. + // "withCredentials" only exists on XMLHTTPRequest2 objects. + xhr.open(`GET`, url, true); + + } else if (typeof XDomainRequest != `undefined`) { + + // Otherwise, check if XDomainRequest. + // XDomainRequest only exists in IE, and is IE's way of making CORS requests. + xhr = new XDomainRequest(); + xhr.open(`GET`, url); + + } else { + + // Otherwise, CORS is not supported by the browser. + xhr = null; + + } + return xhr; + }; + + const scriptElement = document.getElementById(`iwsy-script`); + if (scriptElement) { + const request = createCORSRequest(`${scriptElement.innerText}?v=${Math.floor(Date.now())}`); + if (!request) { + throw Error(`Unable to access the JSON script`); + } + + request.onload = () => { + if (200 <= request.status && request.status < 400) { + const script = JSON.parse(request.responseText); + IWSY(document.getElementById(`iwsy-container`), script); + } else { + throw Error(`Unable to access the JSON script`); + } + }; + + request.onerror = () => { + throw Error(`Unable to access the JSON script`); + }; + + request.send(); + } +}; + +// Wait for a click/tap or a keypress to start +document.addEventListener(`click`, init); +document.onkeydown = function (event) { + if (event.code === `Enter`) { + mode = `auto`; + } + setup(); + return true; +}; \ No newline at end of file diff --git a/iwsy/resources/ecs/container.txt b/iwsy/resources/ecs/container.txt deleted file mode 100644 index 4e2276d..0000000 --- a/iwsy/resources/ecs/container.txt +++ /dev/null @@ -1,12 +0,0 @@ -! Container - - script Container - - import div Panel and variable Presentation - - on message go to Start - set ready - stop - -Start: - stop \ No newline at end of file diff --git a/iwsy/resources/ecs/defaults.txt b/iwsy/resources/ecs/defaults.txt deleted file mode 100644 index de42204..0000000 --- a/iwsy/resources/ecs/defaults.txt +++ /dev/null @@ -1,157 +0,0 @@ -! Defaults - - script Defaults - - import div Panel and variable Presentation - - div GlobalTitle - div GlobalPanel - div ContainerTitle - div ContainerPanel - div DefaultsTitle - div DefaultsPanel - div Row - div Label - input GlobalInput - input ContainerInput - input DefaultsInput - variable Globals - variable Container - variable Defaults - variable GlobalItems - variable ContainerItems - variable DefaultsItems - variable Name - variable Value - variable N - - on message go to Start - set ready - stop - -Start: - if the message is `save` - begin - stop - end - - clear Panel - - set style `display` of Panel to `flex` - set style `flex-direction` of Panel to `column` - - create GlobalTitle in Panel - set the style of GlobalTitle to `font-weight:bold;font-size:110%;background:lightgray;` - cat `padding:0.2em;text-align:center;margin-top:0.5em` - - create GlobalPanel in Panel - set the style of GlobalPanel to - `height:auto;max-height:25%;overflow-y:scroll;margin-top:0.5em` - - create ContainerTitle in Panel - set the style of ContainerTitle to `font-weight:bold;font-size:110%;background:lightgray;` - cat `padding:0.2em;text-align:center;margin-top:1em` - - create ContainerPanel in Panel - set the style of ContainerPanel to - `height:auto;max-height:20%;overflow-y:scroll;margin-top:0.5em` - - create DefaultsTitle in Panel - set the style of DefaultsTitle to `font-weight:bold;font-size:110%;background:lightgray;` - cat `padding:0.2em;text-align:center;margin-top:1em` - - create DefaultsPanel in Panel - set the style of DefaultsPanel to - `flex:1;max-height:60%;overflow-y:scroll;margin-top:0.5em` - - set GlobalItems to array - json add `title` to GlobalItems - json add `description` to GlobalItems - json add `aspectW` to GlobalItems - json add `aspectH` to GlobalItems - - set ContainerItems to array - json add `background` to ContainerItems - json add `border` to ContainerItems - - set DefaultsItems to array - json add `fontFamily` to DefaultsItems - json add `fontSize` to DefaultsItems - json add `fontWeight` to DefaultsItems - json add `fontStyle` to DefaultsItems - json add `fontColor` to DefaultsItems - json add `textAlign` to DefaultsItems - json add `textMarginLeft` to DefaultsItems - json add `textMarginTop` to DefaultsItems - json add `blockLeft` to DefaultsItems - json add `blockTop` to DefaultsItems - json add `blockWidth` to DefaultsItems - json add `blockBackground` to DefaultsItems - json add `blockBorder` to DefaultsItems - json add `blockBorderRadius` to DefaultsItems - - put property `global` of Presentation into Globals - put property `container` of Presentation into Container - put property `defaults` of Presentation into Defaults - - clear GlobalPanel - clear ContainerPanel - clear DefaultsPanel - set the content of GlobalTitle to `Global defaults` - set the content of ContainerTitle to `Container defaults` - set the content of DefaultsTitle to `Block defaults` - - put the json count of GlobalItems into N - set the elements of GlobalInput to N - put 0 into N - while N is less than the elements of GlobalInput - begin - create Row in GlobalPanel - set the style of Row to `display:flex;margin-top:0.2em` - create Label in Row - set the style of Label to `width:10em` - put element N of GlobalItems into Name - set the content of Label to Name - create GlobalInput in Row - set the style of GlobalInput to `flex:1;margin-right:0.5em` - put property Name of Globals into Value - set the text of GlobalInput to Value - add 1 to N - end - - put the json count of ContainerItems into N - set the elements of ContainerInput to N - put 0 into N - while N is less than the elements of ContainerInput - begin - create Row in ContainerPanel - set the style of Row to `display:flex;margin-top:0.2em` - create Label in Row - set the style of Label to `width:10em` - put element N of ContainerItems into Name - set the content of Label to Name - create ContainerInput in Row - set the style of ContainerInput to `flex:1;margin-right:0.5em` - put property Name of Container into Value - set the text of ContainerInput to Value - add 1 to N - end - - put the json count of DefaultsItems into N - set the elements of DefaultsInput to N - put 0 into N - while N is less than the elements of DefaultsInput - begin - create Row in DefaultsPanel - set the style of Row to `display:flex;margin-top:0.2em` - create Label in Row - set the style of Label to `width:10em` - put element N of DefaultsItems into Name - set the content of Label to Name - create DefaultsInput in Row - set the style of DefaultsInput to `flex:1;margin-right:0.5em` - put property Name of Defaults into Value - set the text of DefaultsInput to Value - add 1 to N - end - stop \ No newline at end of file diff --git a/iwsy/resources/ecs/globals.txt b/iwsy/resources/ecs/globals.txt deleted file mode 100644 index 41d4d8f..0000000 --- a/iwsy/resources/ecs/globals.txt +++ /dev/null @@ -1,12 +0,0 @@ -! Globals - - script Globals - - import div Panel and variable Presentation - - on message go to Start - set ready - stop - -Start: - stop \ No newline at end of file diff --git a/iwsy/resources/ecs/main.txt b/iwsy/resources/ecs/main.txt index 44d53db..c752e7c 100644 --- a/iwsy/resources/ecs/main.txt +++ b/iwsy/resources/ecs/main.txt @@ -14,6 +14,7 @@ div StepsPanel div BlocksPanel div ContentPanel + div Player span Status span Span input NameEditor @@ -92,15 +93,12 @@ L2: else set the style of Body to `width:100%;height:100%;display:flex` +! The left-hand panel create Left in Body - set the style of Left to - `flex:1;height:100%;display:flex;flex-direction:column;border-right:1px solid black;margin-right:0.5em` - - create Right in Body - set the style of Right to `flex:1;height:100%;display:flex;flex-direction:column;overflow:hidden` + set the style of Left to `flex:1;height:100%;border-right:1px solid black;margin-right:0.5em` create Controls in Left - set the style of Controls to `flex:1;padding:0 0.5em` + set the style of Controls to `padding:0 0.5em` create Buttons in Controls set the style of Buttons to `width:100%;padding:0.5em 0` @@ -114,9 +112,6 @@ L2: create NameEditor in ScriptName set the style of NameEditor to `flex:85;display:inline-block` - create ContentDiv in Right - set the style of ContentDiv to `width:100%;height:100%;position:relative` - create Link in Buttons create New in Link set the style of New to `width:40px;margin-right:0.5em` @@ -151,13 +146,23 @@ L2: if Mobile set the style of Status to `height:1em` else set the style of Status to `float:right;margin:0.5em 0 0 0;color:green` + create Player in Left + set the style of Player to `margin:0.5em` + iwsy init + +! The right-hand panel + create Right in Body + set the style of Right to `flex:1;height:100%;display:flex;flex-direction:column;overflow:hidden` + + create ContentDiv in Right + set the style of ContentDiv to `width:100%;height:100%;position:relative` + create Tabs in ContentDiv set the style of Tabs to `width:100%;padding:0.5em 0;text-align:center` - put the width of Tabs into N - divide N by 3 set the elements of SectionButton to 3 + divide 100 by the elements of SectionButton giving N create Tab in Tabs - set the style of Tab to `display:inline-block;width:` cat N cat `px` + set the style of Tab to `display:inline-block;width:` cat N cat `%` index SectionButton to 0 create SectionButton in Tab set the style of SectionButton to `width:100%` @@ -165,7 +170,7 @@ L2: create StepsPanel in ContentDiv set the style of StepsPanel to `position:absolute;left:0;top:2.5em;width:100%;height:calc(100% - 2.5em)` create Tab in Tabs - set the style of Tab to `display:inline-block;width:` cat N cat `px` + set the style of Tab to `display:inline-block;width:` cat N cat `%` index SectionButton to 1 create SectionButton in Tab set the style of SectionButton to `width:100%` @@ -173,15 +178,13 @@ L2: create BlocksPanel in ContentDiv set the style of BlocksPanel to `position:absolute;left:0;top:2.5em;width:100%;height:calc(100% - 2.5em)` create Tab in Tabs - set the style of Tab to `display:inline-block;width:` cat N cat `px` + set the style of Tab to `display:inline-block;width:` cat N cat `%` index SectionButton to 2 create SectionButton in Tab set the style of SectionButton to `width:100%` set the content of SectionButton to `Content` create ContentPanel in ContentDiv set the style of ContentPanel to `position:absolute;left:0;top:2.5em;width:100%;height:calc(100% - 2.5em)` - create Tab in Tabs - set the style of Tab to `display:inline-block;width:` cat N cat `px` put 0 into Section index SectionButton to 0 @@ -308,6 +311,8 @@ L2: gosub to SetupContent put 0 into N gosub to SelectSection + + on message iwsy goto the message stop CreateNewPresentation: @@ -489,6 +494,7 @@ SelectFile: set the content of Status to `Presentation '` cat File cat `' loaded` fork to ResetStatus set ShowRun + iwsy load Player Presentation CloseBrowser: set style `background-color` of Overlay to `rgba(0,0,0,0.0)` diff --git a/iwsy/resources/ecs/mostrami.txt b/iwsy/resources/ecs/mostrami.txt deleted file mode 100644 index 2cbb885..0000000 --- a/iwsy/resources/ecs/mostrami.txt +++ /dev/null @@ -1,560 +0,0 @@ -! Mostrami - - script Mostrami - - div Body - div Left - div Right - div Controls - div ContentDiv - div Buttons - div Tabs - div Tab - div ScriptName - div StepsPanel - div BlocksPanel - div ContentPanel - div DefaultsPanel - span Status - span Span - input NameEditor - button SectionButton - img New - img Open - img Save - img RunStop - img Delete - img Cycle - a Link - module StepsModule - module BlocksModule - module ContentModule - module DefaultsModule - variable Mobile - variable Current - variable Content - variable Script - variable Presentation - variable Name - variable CurrentName - variable PasswordValid - variable ShowRun - variable ReadOnly - variable PasswordRequested - variable Password - variable CallStack - variable Message - variable Section - variable Item - variable CurrentScriptName - variable N - - ! The browser - div Overlay - div Scroller - div Media - div FileListing - div FileRow - div LowerPanel - button CloseButton - a FileName - variable Alpha - variable List - variable FileList - variable FileCount - variable File - variable Files - variable FileIsOpen - -! Test if site is on a static host - clear ReadOnly - rest get List from `_list/scripts` - or begin - print `Static site` - set ReadOnly - go to L2 - end -L2: - clear PasswordRequested - put empty into CallStack - history set - on restore - begin - put the json count of CallStack into N - end - if portrait - begin - if mobile set Mobile else clear Mobile - end - - set the title to `Mostrami Pro` - create Body - if Mobile - set the style of Body to `width:100%;height:100%` - else - set the style of Body to `width:100%;height:100%;display:flex` - - create Left in Body - set the style of Left to `flex:1;height:100%;display:flex;flex-direction:column;overflow:hidden` - - create Right in Body - set the style of Right to `flex:1;height:100%;display:flex;flex-direction: column` - - create Controls in Left - set the style of Controls to `flex:1;background:lightgray;padding:0 0.5em` - - create Buttons in Controls - set the style of Buttons to `width:100%;padding:0.5em 0` - - create ContentDiv in Left - set the style of ContentDiv to `width:100%;height:100%;position:relative` - - create Link in Buttons - create New in Link - set the style of New to `width:40px;margin-right:0.5em` - set attribute `src` of New to `resources/icon/new.png` - set attribute `title` of New to `New` - create Open in Link - set the style of Open to `width:40px;margin-right:0.5em` - set attribute `src` of Open to `resources/icon/open.png` - set attribute `title` of Open to `Open` - create Link in Buttons - create Save in Link - set the style of Save to `width:40px;margin-right:1.5em` - set attribute `src` of Save to `resources/icon/save.png` - set attribute `title` of Save to `Save` - create Link in Buttons - create Delete in Link - set the style of Delete to `width:40px;margin-right:1.5em` - set attribute `src` of Delete to `resources/icon/trash.png` - set attribute `title` of Delete to `Delete` - create Link in Buttons - create RunStop in Link - set the style of RunStop to `width:40px;margin-right:1.5em` - set attribute `src` of RunStop to `resources/icon/run.png` - set attribute `title` of RunStop to `Run` - create Link in Buttons - create Cycle in Link - set the style of Cycle to `width:40px` - set attribute `src` of Cycle to `resources/icon/cycle.png` - set attribute `title` of Cycle to `Cycle screens` - - create Status in Buttons - if Mobile set the style of Status to `height:1em` - else set the style of Status to `float:right;margin:0.5em 0 0 0;color:green` - - create ScriptName in Controls - set the style of ScriptName to `display:flex` - if Mobile set style `display` of ScriptName to `none` - create Span in ScriptName - set the style of Span to `flex:15` - set the content of Span to `Script name: ` - create NameEditor in ScriptName - set the style of NameEditor to `flex:85;display:inline-block` - - create Tabs in Controls - set the style of Tabs to `width:100%;padding:0.5em 0;text-align:center` - put the width of Tabs into N - divide N by 4 - set the elements of SectionButton to 4 - create Tab in Tabs - set the style of Tab to `display:inline-block;width:` cat N cat `px` - index SectionButton to 0 - create SectionButton in Tab - set the style of SectionButton to `width:100%` - set the content of SectionButton to `Steps` - create StepsPanel in ContentDiv - set the style of StepsPanel to `position:absolute;left:0;top:0;width:100%;height:100%;` - create Tab in Tabs - set the style of Tab to `display:inline-block;width:` cat N cat `px` - index SectionButton to 1 - create SectionButton in Tab - set the style of SectionButton to `width:100%` - set the content of SectionButton to `Blocks` - create BlocksPanel in ContentDiv - set the style of BlocksPanel to `position:absolute;left:0;top:0;width:100%;height:100%;` - create Tab in Tabs - set the style of Tab to `display:inline-block;width:` cat N cat `px` - index SectionButton to 2 - create SectionButton in Tab - set the style of SectionButton to `width:100%` - set the content of SectionButton to `Content` - create ContentPanel in ContentDiv - set the style of ContentPanel to `position:absolute;left:0;top:0;width:100%;height:100%;` - create Tab in Tabs - set the style of Tab to `display:inline-block;width:` cat N cat `px` - index SectionButton to 3 - create SectionButton in Tab - set the style of SectionButton to `width:100%` - set the content of SectionButton to `Defaults` - create DefaultsPanel in ContentDiv - set the style of DefaultsPanel to `position:absolute;left:0;top:0;width:100%;height:100%;` - - put 0 into Section - index SectionButton to 0 - on click SectionButton gosub to SelectSection - -! Create the file browser - create Overlay in Body - set the style of Overlay to - `position:absolute;top:0;left:0;width:100vw;height:100vh;background:rgba(0,0,0,0.0);display:none` - - create Media in Overlay - set style of Media to `display:none;width:100%;height:100%;text-align:center` - - create FileListing in Media - set the style of FileListing to - `display:none;width:50%;height:75%;margin:auto;background-color:white;` - cat `padding:2em 2em 3em 2em;text-align:center;position: absolute;top: 50%;left: 50%;` - cat `transform: translateX(-50%) translateY(-50%)` - - create Scroller in FileListing - set the style of Scroller to `height:100%;overflow:scroll;text-align:left` - - create LowerPanel in FileListing - - create CloseButton in LowerPanel - set the style of CloseButton to `margin-left:2em` - set the text of CloseButton to `Close` - - put empty into Current - - on click New - begin -! gosub to StopTestModule - if Presentation is not Current - begin - if confirm `Content has changed. Do you want to save it?` - begin - put the content of NameEditor into Name - if Name is empty - begin - gosub to SetStatusRed - set the content of Status to `No script name has been given` - go to ResetStatus - end - if PasswordValid rest post Presentation to `_save/json/` cat Name - else put Presentation into storage as CurrentName - end - end - clear FileIsOpen - set the content of NameEditor to empty - put empty into CurrentScriptName - gosub to CreateNewPresentation - put Presentation into Current - gosub to UpdateCurrentSection - end - - on click Open go to DoOpen - - on click Save - begin - gosub to GetPassword - put the content of NameEditor into Name - if Name is empty - begin - gosub to SetStatusRed - set the content of Status to `No script name has been given` - go to ResetStatus - end - if the position of `.json` in Name is -1 put Name cat `.json` into Name - replace ` ` with `_` in Name - set the content of NameEditor to Name - if Name is not CurrentScriptName put empty into Current - if Presentation is not Current - begin - if PasswordValid rest post Presentation to `_save/json/` cat Name - else put Presentation into storage as Name - put Presentation into Current - gosub to SetStatusGreen - set the content of Status to `Presentation '` cat Name cat `' saved` - put Name into CurrentScriptName - fork to ResetStatus - end - else - begin - gosub to SetStatusGreen - set the content of Status to `Nothing has changed` - fork to ResetStatus - end - end - - on click Delete - begin - gosub to GetPassword - put the content of NameEditor into Name - if Name is empty - begin - gosub to SetStatusGreen - set the content of Status to `Nothing to delete` - go to ResetStatus - end - if confirm `Are you sure you want to delete "` cat Name cat `"?` - begin - if PasswordValid rest post to `_delete/json/` cat Name - else remove Name from storage - gosub to SetStatusGreen - set the content of Status to `Script "` cat Name cat `" deleted` - set the content of NameEditor to empty - put empty into CurrentScriptName - put empty into Presentation - put Presentation into Current - go to ResetStatus - end - end - - gosub to CreateNewPresentation - gosub to SetupSteps - gosub to SetupBlocks - gosub to SetupContent - gosub to SetupDefaults - gosub to SelectSection - put Presentation into Current - stop - -CreateNewPresentation: - set Presentation to object - set Item to object - set property `global` of Presentation to Item - set property `container` of Presentation to Item - set property `defaults` of Presentation to Item - set property `blocks` of Presentation to Item - set property `content` of Presentation to Item - set Item to array - set property `steps` of Presentation to Item - return - -SetupSteps: - if StepsModule is not running - begin - rest get Script from `/resources/ecs/steps.txt` - run Script with StepsPanel and Presentation as StepsModule - end - return - -SetupBlocks: - if BlocksModule is not running - begin - rest get Script from `/resources/ecs/blocks.txt` - run Script with BlocksPanel and Presentation as BlocksModule - end - return - -SetupContent: - if ContentModule is not running - begin - rest get Script from `/resources/ecs/content.txt` - run Script with ContentPanel and Presentation as ContentModule - end - return - -SetupDefaults: - if DefaultsModule is not running - begin - rest get Script from `/resources/ecs/defaults.txt` - run Script with DefaultsPanel and Presentation as DefaultsModule - end - return - -SelectSection: - put the index of SectionButton into N - index SectionButton to Section - set style `background` of SectionButton to `` - put N into Section - index SectionButton to Section - set style `background` of SectionButton to `lightgray` - -UpdateCurrentSection: - set style `display` of StepsPanel to `none` - set style `display` of BlocksPanel to `none` - set style `display` of ContentPanel to `none` - set style `display` of DefaultsPanel to `none` - if Section is 0 - begin - set style `display` of StepsPanel to `block` - send to StepsModule - end - else if Section is 1 - begin - set style `display` of BlocksPanel to `block` - send to BlocksModule - end - else if Section is 2 - begin - set style `display` of ContentPanel to `block` - send to ContentModule - end - else if Section is 3 - begin - set style `display` of DefaultsPanel to `block` - send to DefaultsModule - end - return - -DoOpen: -! gosub to StopTestModule - gosub to GetPassword - - clear FileIsOpen - if Presentation is not Current - begin - if confirm `Content has changed. Do you want to save it?` - begin - if PasswordValid rest post Content to `_save/json/` cat Name - else put Content into storage as Name - end - end - - ! Animate the background - set style `display` of Overlay to `block` - put 0 into Alpha - while Alpha is less than 8 - begin - set style `background-color` of Overlay to `rgba(0,0,0,0.` cat Alpha cat `)` - wait 4 ticks - add 1 to Alpha - end - wait 10 ticks - - ! Make the browser panel visible - set style `display` of Media to `block` - set style `display` of FileListing to `inline-block` - - ! Fill the browser with content from the server - if PasswordValid - begin - rest get Files from `_list/json` - put the json count of Files into FileCount - put empty into Content - put 0 into N - while N is less than FileCount - begin - put element N of Files into Item - if property `type` of Item is `json` json add property `name` of Item to Content - add 1 to N - end - end - else - begin - get Files from storage - put the json count of Files into FileCount - put empty into Content - put 0 into N - while N is less than FileCount - begin - put element N of Files into Item - if left 1 of Item is not `.` json add Item to Content - add 1 to N - end - end - json sort Content - put empty into FileList - put the json count of Content into FileCount - set the elements of File to FileCount - set the elements of FileName to FileCount - ! Add a row for each file - put 0 into N - while N is less than FileCount - begin - index File to N - index FileName to N - put `
` into File - replace `INDEX` with N in File - if N is even replace `ODDEVEN` with `ec-even` in File - else replace `ODDEVEN` with `ec-odd` in File - put FileList cat File into FileList - add 1 to N - end - - set the content of Scroller to FileList - ! Add the document names - put 0 into N - while N is less than FileCount - begin - index File to N - index FileName to N - put element N of Content into File - attach FileRow to `ec-file-row-` cat N - attach FileName to `ec-file-name-` cat N - set the content of FileName to File - if N is even set style `background` of FileRow to `lightgray` - on click FileName go to SelectFile - add 1 to N - end - on click CloseButton - begin - put Current into Content - go to CloseBrowser - end - stop - -SelectFile: - index File to the index of FileName - set the content of NameEditor to File - put File into CurrentScriptName - if PasswordValid rest get Presentation from `/resources/json/` cat File - else get Presentation from storage as File - put Presentation into Current - gosub to UpdateCurrentSection - set the content of Status to `Presentation '` cat File cat `' loaded` - fork to ResetStatus - set ShowRun - -CloseBrowser: - set style `background-color` of Overlay to `rgba(0,0,0,0.0)` - set style `display` of Overlay to `none` - set style `display` of Media to `none` - stop - -SetStatusRed: - set style `color` of Status to `red` - return - -SetStatusGreen: - set style `color` of Status to `green` - return - -ResetStatus: - wait 2 - set the content of Status to `` - stop - -GetPassword: - if ReadOnly - begin - clear PasswordValid - return - end - if the hostname is `localhost` go to SetPasswordValid - if the hostname is `127.0.0.1` go to SetPasswordValid - - if not PasswordRequested - begin - set PasswordRequested - if hostname is `localhost` goto SetPasswordValid - if hostname is `127.0.0.1` goto SetPasswordValid - get Password from storage as `.password` - if Password is empty - begin - put `Please provide the admin password` cat newline - cat `or click OK to use private browser storage.` into Message - put prompt Message with `` into Password - end - rest get PasswordValid from `_verify/` cat Password - or begin - clear PasswordValid - return - end - if PasswordValid is `yes` - begin - put Password into storage as `.password` - set PasswordValid - end - else clear PasswordValid - end - return - -SetPasswordValid: - set PasswordValid - return \ No newline at end of file diff --git a/iwsy/resources/ecs/steps.txt b/iwsy/resources/ecs/steps.txt index f811b89..e24738b 100644 --- a/iwsy/resources/ecs/steps.txt +++ b/iwsy/resources/ecs/steps.txt @@ -36,6 +36,7 @@ img PlusIcon img DeleteIcon img DeleteStep + img ShowStep a Link variable Steps variable SelectedStep @@ -44,7 +45,6 @@ variable Blocks variable Block variable Contents - variable Content variable Target variable Types variable Duration @@ -104,6 +104,7 @@ Restart: put property `steps` of Presentation into Steps put the json count of Steps into N + set the elements of ShowStep to N set the elements of StepButton to N set the elements of DeleteStep to N set the elements of TitleInput to N @@ -117,10 +118,17 @@ Restart: set the style of Row to `width:100%` create Row1 in Row set the style of Row1 to `display:flex;margin-bottom:0.2em` + create Cell in Row1 + set the style of Cell to `width:1.4em;text-align:center` + create Link in Cell + index ShowStep to N + create ShowStep in Link + set the style of ShowStep to `width:1em;margin-top:0.1em` + set attribute `src` of ShowStep to `resources/icon/binoculars.png` create StepButton in Row1 set the style of StepButton to `flex:1` put element N of Steps into CurrentStep - set the text of StepButton to property `comment` of CurrentStep + set the text of StepButton to property `title` of CurrentStep create Cell in Row1 set the style of Cell to `width:1.4em;text-align:center` index DeleteStep to N @@ -131,7 +139,7 @@ Restart: index Editor to N create Editor in Row add 1 to N - end + end on click StepButton begin gosub to SaveCurrentStep @@ -176,6 +184,11 @@ Restart: set property `steps` of Presentation to Steps go to Restart end + on click ShowStep + begin + put the index of ShowStep into N + send N to parent + end ! Set up the fixed lists set ActionNames to array @@ -246,7 +259,7 @@ ASA3: CreateNewStep: set CurrentStep to object - set property `comment` of CurrentStep to `New step` + set property `title` of CurrentStep to `New step` set property `action` of CurrentStep to `` set property `label` of CurrentStep to `` return @@ -272,7 +285,7 @@ ReloadStepEditor: index TitleInput to SelectedStep create TitleInput in TD set the style of TitleInput to `width:100%` - set the content of TitleInput to property `comment` of CurrentStep + set the content of TitleInput to property `title` of CurrentStep create TR in Table create TD in TR set the style of TD to `width:6em` @@ -316,7 +329,7 @@ ReloadStepEditor: if Response begin index StepButton to SelectedStep - set property `comment` of CurrentStep to TitleInput + set property `title` of CurrentStep to TitleInput put the selected item in ActionSelect into Action gosub to CreateNewAction clear Table @@ -682,7 +695,7 @@ CreateNewAction: index TitleInput to SelectedStep if the text of TitleInput is empty begin - set property `comment` of CurrentStep to `New step: ` cat Action + set property `title` of CurrentStep to `New step: ` cat Action end set property `action` of CurrentStep to Action set property `label` of CurrentStep to empty @@ -797,7 +810,7 @@ SaveCurrentStep: if SelectedStep is -1 return index TitleInput to SelectedStep put element SelectedStep of Steps into CurrentStep - set property `comment` of CurrentStep to the text of TitleInput + set property `title` of CurrentStep to the text of TitleInput index StepButton to SelectedStep set the text of StepButton to the content of TitleInput index LabelInput to SelectedStep diff --git a/iwsy/resources/json/test.json b/iwsy/resources/json/test.json index e097c68..8d8e21f 100644 --- a/iwsy/resources/json/test.json +++ b/iwsy/resources/json/test.json @@ -1 +1 @@ -{"blocks":{"title":{"background":"","border":"","borderRadius":"","fontColor":"","fontFamily":"","fontSize":30,"fontStyle":"","fontWeight":"","height":"100%","left":0,"textAlign":"","textMarginLeft":"","textMarginTop":"","top":0,"width":"100%"}},"content":{"main title":{"content":"This is my title","type":"text"}},"steps":[{"comment":"Init","action":"init","label":"","aspect ratio":"16:9","background":"yellow","border":"","title":"My first presentation"},{"comment":"Setup main title","action":"set content","label":"","blocks":[{"block":"title","content":"main title"}]}]} \ No newline at end of file +{"blocks":{"title":{"background":"","border":"","borderRadius":"","fontColor":"","fontFamily":"","fontSize":30,"fontStyle":"","fontWeight":"","height":"100%","left":0,"textAlign":"","textMarginLeft":"","textMarginTop":"","top":0,"width":"100%"}},"content":{"main title":{"content":"This is my title","type":"text"}},"steps":[{"title":"Init","action":"init","label":"","aspect ratio":"16:9","background":"yellow","border":"1px solid red","title":"My first presentation"},{"title":"Setup main title","action":"set content","label":"","blocks":[{"block":"title","content":"main title"}]},{"title":"Fade up title","action":"fade up","label":"","blocks":[],"duration":1}]} diff --git a/js/plugins/iwsy.js b/js/plugins/iwsy.js index c707623..e8ee213 100644 --- a/js/plugins/iwsy.js +++ b/js/plugins/iwsy.js @@ -11,16 +11,46 @@ const EasyCoder_IWSY = { const lino = compiler.getLino(); const action = compiler.nextToken(); - if ([`init`, `show`].includes(action)) { - compiler.next(); - compiler.addCommand({ - domain: `iwsy`, - keyword: `iwsy`, - lino, - action - }); - return true; - } + switch (action) { + case `load`: + if (compiler.nextIsSymbol()) { + const playerRecord = compiler.getSymbolRecord(); + if (playerRecord.keyword === `div`) { + const script = compiler.getNextValue(); + compiler.addCommand({ + domain: `iwsy`, + keyword: `iwsy`, + lino, + action, + player: playerRecord.name, + script + }); + return true; + } + } + break; + case `init`: + compiler.next(); + compiler.addCommand({ + domain: `iwsy`, + keyword: `iwsy`, + lino, + action + }); + return true; + case `goto`: + const target = compiler.getNextValue(); + compiler.addCommand({ + domain: `iwsy`, + keyword: `iwsy`, + lino, + action, + target + }); + return true; + default: + break; + } return false; }, @@ -33,8 +63,18 @@ const EasyCoder_IWSY = { function () { program.run(command.pc + 1); }); + return 0; + case `load`: + const playerRecord = program.getSymbolRecord(command.player); + const player = playerRecord.element[playerRecord.index]; + player.innerHTML = ``; + player.style.background = `none`; + player.style.border = `none`; + const script = program.getValue(command.script); + EasyCoder.iwsyGotoStep = IWSY(player, JSON.parse(script)); break; - case `show`: + case `goto`: + EasyCoder.iwsyGotoStep(program.getValue(command.target)); break; } return command.pc + 1;