%% %% This is file `acromemory.sty', %% generated with the docstrip utility. %% %% The original source files were: %% %% acromemory.dtx (with options: `copyright,package') %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% acromemory.sty package, %% %% Copyright (C) 2006--2017 D. P. Story %% %% dpstory@acrotex.net %% %% %% %% This program can redistributed and/or modified under %% %% the terms of the LaTeX Project Public License %% %% Distributed from CTAN archives in directory %% %% macros/latex/base/lppl.txt; either version 1.2 of %% %% the License, or (at your option) any later version. %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \NeedsTeXFormat{LaTeX2e} \ProvidesPackage{acromemory} [2017/02/23 v1.1 AcroMemory (dps)] \RequirePackage{xkeyval} \DeclareOptionX{acromemory1}{\acromemoryitrue} \DeclareOptionX{acromemory2}{\acromemoryifalse} \DeclareOptionX{iconfile}{\def\iconsInOneFile{true}} \def\iconsInOneFile{false} \DeclareOptionX{includehelp}{\includehelptrue} \newif\ifincludehelp \includehelpfalse \newif\ifacromemoryi \acromemoryifalse \ProcessOptionsX \RequirePackage{graphicx} \RequirePackage{comment} \ifacromemoryi \def\RanIdentifier{\@gobble} \includecomment{acromemory1} \excludecomment{acromemory2} \excludecomment{needhelp} \else \def\RanIdentifier{R\@gobble} \includecomment{acromemory2} \excludecomment{acromemory1} \ifincludehelp \includecomment{needhelp} \else \excludecomment{needhelp} \fi \fi \def\theTotalTiles#1{\def\nTotalTiles{#1}} \def\theNumRows#1{\def\nRows{#1}} \def\theNumCols#1{\def\nCols{#1}} \newcommand{\theImportPath}[2][]{% \ifacromemoryi \def\imageImportPath{#2} \def\importpath{#2} \else \def\argi{#1}\ifx\argi\@empty \def\imageImportPath{#2} \def\importpath{#2} \else \def\imageImportPath{#1} \def\importpath{#2} \fi \fi } \def\theIconExt#1{\def\iconsExt{#1}} \def\iconsExt{pdf} \def\theTeXImageWidth#1{\def\texImageWidth{#1}% {\dimen0 = \texImageWidth \xdef\imageWidth{\strip@pt\dimen0 }}% } \newcommand{\provideDimensions}[3][]{% \def\argi{#1}\ifx\argi\@empty {\dimen0 = #2 \xdef\trueImageWidth{\strip@pt\dimen0 }% \dimen0 = #3 \xdef\trueImageHeight{\strip@pt\dimen0 }}% \else \def\trueImageWidth{#1}\def\trueImageHeight{#2}% \fi \def\bProvideDimen{true}% } \def\bProvideDimen{false}% \def\trueImageWidth{0}\def\trueImageHeight{0}% \def\bDebug{\def\memDebug{true}} \def\memDebug{false} \newcommand{\helpImage}[1][]{{% \ifincludehelp{\setbox0 = \hbox{% \includegraphics[draft,width=\helpImageWidth]% {\imageImportPath}}%[\Ff\FfReadOnly] \dimen0=\ht0 \advance\dimen0by14bp\ht0=\dimen0 \pushButton[\BC{}\BG{}\S{S}#1]{memoryhelp}{\the\wd0}{\the\ht0}}\fi }} \newcommand{\rolloverHelpButton}[3][]{% \ifincludehelp \pushButton[\CA{Help}\BC{0 0 1}\BG{0.89 0.9 0.9} \AA{\AAMouseEnter{\JS{% var f = this.getField("memoryhelp");\r oIcon = f.buttonGetIcon(1);\r f.buttonPosition = position.iconTextV;\r f.buttonSetIcon(oIcon,0);\r f.buttonSetCaption({cCaption: "\helpCaption"});\r f.textColor=color.blue;\r }}% \AAMouseExit{\JS{% var f = this.getField("memoryhelp");\r f.buttonPosition = position.iconOnly;\r f.buttonSetIcon(nullIcon,0); }}}#1]{checkhelp}{#2}{#3}% \fi } \newcommand{\setHelpImageWidth}[1]{\def\helpImageWidth{#1}} \def\helpImageWidth{1in} \def\theHelpCaption#1{\def\helpCaption{#1}} \theHelpCaption{A little help} \newcommand{\messageBox}[3][]{% \textField[#1\Ff\FfMultiline]{MsgBox}{#2}{#3}} \newcommand{\playItAgain}[3][]{\ifacromemoryi{\small \pushButton[\CA{Play again}#1\A{\JS{playagain();}}]% {playAgain}{#2}{#3}}% \fi } \def\ulCornerHere{\makebox[0pt][l]% {\pushButton[\autoCenter{n}]{ulcorner}{0pt}{0pt}% \pushButton[\autoCenter{n}\BC{}\BG{}\FB{true}\I{null}\TP{1}]{nullIconBtn}{0pt}{0pt}% }} \def\LulCornerHere{\makebox[0pt][l]% {\pushButton[\autoCenter{n}]{Lulcorner}{0pt}{0pt}% \pushButton[\autoCenter{n}\BC{}\BG{}\FB{true}\I{null}\TP{1}]{nullIconBtn}{0pt}{0pt}% }} \def\RulCornerHere{\makebox[0pt][l]% {\pushButton[\autoCenter{n}]{Rulcorner}{0pt}{0pt}}} \def\reserveSpaceByDimension#1#2{% \hbox{\ifpreview\setlength\fboxrule{0.4pt}\setlength\fboxsep{0pt}% \@tempdima=#1\advance\@tempdima by-\fboxrule \@tempdimb=#2\advance\@tempdimb by-\fboxrule \fbox{\parbox[t][\@tempdimb][t]{\@tempdima}{\kern0pt\hfill\vfill}}% \else\parbox[t][#2][t]{#1}{\kern0pt\hfill\vfill}\fi}% } \newcommand{\reserveSpaceByFile}[1][\imageImportPath]% {{\setbox0=\hbox{\includegraphics[draft,width=\texImageWidth]{#1}}% \reserveSpaceByDimension{\wd0}{\ht0}}} \begin{insDLJS*}[_MemLoaded]{memjs} \begin{newsegment}{AcroMemory 1: Global Data and Initialization} // Global Data: _MemLoaded=true; var randomDPS = new Array(\nTotalTiles+1); var imageNames = new Array(); imageNames.push("null"); var dpsl = randomDPS.length; var timeout = 10; var shutdown, rAE; var ok2Continue = true; var nRows = \nRows; var nCols = \nCols; var nCorrect = 0; var nAttempts = 0; for (i=1; i<=\nTotalTiles; i++) randomDPS[i]=i; var f=this.getField("nullIconBtn"); var nullIcon=f.buttonGetIcon(); var debug = \memDebug; \end{newsegment} \begin{acromemory1} \begin{newsegment}{AcroMemory 2: Initialize Pic Names} var nttl = \nTotalTiles/2; for ( var i = 1; i <= nttl; i++) { imageNames.push("pic"+i +".0"); imageNames.push("pic"+i +".1"); } var currentChoice = ""; var currentTile1 = 0; var currentTile2 = 0; var currentIconName = ""; \end{newsegment} \end{acromemory1} \begin{acromemory2} \begin{newsegment}{AcroMemory 2: Initialize Pic Names} var nttl = \nTotalTiles; for ( var i = 1; i <= nttl; i++) { imageNames.push("pic."+i); } var LcurrentChoice = 0; var LcurrentTile = 0; var RcurrentChoice = 0; var RcurrentTile = 0; \end{newsegment} \end{acromemory2} \begin{newsegment}{AcroMemory 3: Bubble Sort} // Clear DPS: function clearDPS() { for ( var i=1; i<=\nTotalTiles; i++ ) { var f = this.getField("Mem\RanIdentifier button."+i); f.buttonSetIcon(nullIcon); } } // Mixup DPS: function mixupDPS() { var i, rand; for (i=1; i<= \nTotalTiles; i++) { var rand = Math.random(); rand *= dpsl*dpsl; rand = Math.ceil(rand); rand = rand \% dpsl; if (rand == 0 ) rand = 1; temp = randomDPS[i]; randomDPS[i]=randomDPS[rand]; randomDPS[rand]=temp; } } // Show DPS: function showDPS() { for ( var i=1; i<=\nTotalTiles; i++ ) { var oIcon = this.getIcon(imageNames[randomDPS[i]]); var f = this.getField("Mem\RanIdentifier button."+i); f.buttonSetIcon(oIcon); } } // Sortout DPS: begin bubble sort function sortoutDPS() { outerLoop(randomDPS.length-1); } function outerLoop(i) { if ( ok2Continue && (i >= 0) ) shutdown = app.setTimeOut("app.clearTimeOut(shutdown); innerLoop("+i+",1);", timeout); } function innerLoop(i,j) { if ( j <= i ) { if (randomDPS[j-1] > randomDPS[j]) { var temp = randomDPS[j-1]; randomDPS[j-1] = randomDPS[j]; randomDPS[j] = temp; var oIcon = this.getIcon(imageNames[randomDPS[j-1]]); var f = this.getField("Mem\RanIdentifier button."+(j-1)); f.buttonSetIcon(oIcon); var oIcon = this.getIcon(imageNames[randomDPS[j]]); var f = this.getField("Mem\RanIdentifier button."+j); f.buttonSetIcon(oIcon); } j++ if ( ok2Continue ) shutdown = app.setTimeOut("app.clearTimeOut(shutdown); innerLoop("+i+","+j+");", timeout); } else { i--; outerLoop(i); } } function randomizePuzzle() { mixupDPS(); for ( var i=1; i<=\nTotalTiles; i++) { var g = this.getField("Mem\RanIdentifier button."+i); var oIcon = this.getIcon(imageNames[randomDPS[i]]); g.buttonSetIcon(oIcon,1); if (debug) g.buttonSetIcon(oIcon,0); } } \end{newsegment} \begin{acromemory1} \begin{newsegment}{AcroMemory 4: Tile Processing} function selectTile() // right side randomly arranged { var f = event.target; var oIcon = f.buttonGetIcon(1); f.buttonSetIcon(oIcon,0); var fname = f.name; var re1 = /Membutton\.(\d+)/; var index = re1.exec(fname); if (debug) console.println("index = " + index[1]); var thisiconName = imageNames[randomDPS[index[1]]]; if (debug) console.println("thisiconName = " + thisiconName); var re = /pic(\d+)\.(\d)/; var image = re.exec(thisiconName) if (debug) console.println("selected: " + image[1] + "." + image[2]); if ( currentChoice == "" ) { currentChoice = fname; currentTile1=image[1]; currentTile2=image[2]; currentIconName = thisiconName; return; } if ( (image[1] == currentTile1) && (image[2] != currentTile2) ) { // right choice nCorrect++; nAttempts++ f.readonly = true; var g = this.getField(currentChoice); g.readonly = true; reportProgress(nCorrect,nAttempts); resetCounters(); } else { // wrong choice nAttempts++ reportProgress(nCorrect,nAttempts); rAE = app.setTimeOut("resetAfterError(\""+currentChoice+"\",\""+fname+"\")", 1000); resetCounters(); } } function resetCounters () { currentChoice = ""; currentTile1 = 0; currentTile2 = 0; currentIconName = ""; } function resetAfterError(l,r) { try { app.clearTimeOut(rAE); } catch(e) {}; var f = this.getField(l); var g = this.getField(r); if (!debug) g.buttonSetIcon(nullIcon,0); // g.strokeColor=color.black; if (!debug) f.buttonSetIcon(nullIcon,0); // f.strokeColor=color.black; } function executePostGameEffects() {return;} function playagain() { for ( var i=1; i<=\nTotalTiles; i++) { var g = this.getField("Membutton."+i); g.buttonSetIcon(nullIcon,0); } g = this.getField("Membutton"); g.readonly=false; resetCounters(); nCorrect = 0; nAttempts = 0; reportProgress(nCorrect,nAttempts); randomizePuzzle(); } \end{newsegment} \end{acromemory1} \begin{acromemory2} \begin{newsegment}{AcroMemory 4: Tile Processing} function selectRandomTile(nCnt,n) // right side randomly arranged { if ( RcurrentChoice != 0 ) return; RcurrentChoice = nCnt; RcurrentTile = n; nAttempts++; var f = event.target; f.strokeColor = ["RGB", 0, .6, 0]; var oIcon = f.buttonGetIcon(1); f.buttonSetIcon(oIcon,0); if ( LcurrentChoice != 0 ) { if (debug) console.println("LcurrentChoice = " + LcurrentChoice + ", RcurrentChoice = " + RcurrentChoice); if ( LcurrentChoice == nCnt ) {// right answer // need to make right side hidden and readonly // need to make this button readonly var g = this.getField("MemLbutton."+LcurrentChoice); g.strokeColor=color.transparent; g.readonly = true; f.strokeColor=color.transparent; f.readonly = true; if (++nCorrect == \nTotalTiles ) // game complete executePostGameEffects(); reportProgress(nCorrect,nAttempts); resetCounters(); } else { // wrong answer // need to set current choices back to zero reportProgress(nCorrect,nAttempts); rAE = app.setTimeOut("resetAfterError("+LcurrentTile+","+RcurrentTile+")", 1000); resetCounters(); } } } function selectNonRandomTile(nCnt,n) // left side, arranged in natural order { if ( LcurrentChoice != 0 ) return; LcurrentChoice = nCnt; LcurrentTile = n; var f = event.target; f.strokeColor = ["RGB", 0, .6, 0]; var oIcon = f.buttonGetIcon(1); f.buttonSetIcon(oIcon,0); if ( RcurrentChoice != 0 ) { if (debug) console.println("LcurrentChoice = " + LcurrentChoice + ", RcurrentChoice = " + RcurrentChoice); if ( RcurrentChoice == nCnt ) {// right answer // need to make right side hidden and readonly // need to make this button readonly var g = this.getField("MemRbutton."+RcurrentTile); g.strokeColor=color.transparent; g.readonly = true; f.readonly = true; f.strokeColor=color.transparent; if (++nCorrect == \nTotalTiles ) // game complete executePostGameEffects(); reportProgress(nCorrect,nAttempts); resetCounters(); } else { // wrong answer // need to set current choices back to zero reportProgress(nCorrect,nAttempts); rAE = app.setTimeOut("resetAfterError("+LcurrentTile+","+RcurrentTile+")", 1000); resetCounters(); } } } function resetCounters () { LcurrentChoice = 0; RcurrentChoice = 0; LcurrentTile = 0; RcurrentTile = 0; } function resetAfterError(l,r) { try { app.clearTimeOut(rAE); } catch(e) {}; var f = this.getField("MemLbutton."+l); var g = this.getField("MemRbutton."+r); if (!debug) g.buttonSetIcon(nullIcon,0); g.strokeColor=color.black; if (!debug) f.buttonSetIcon(nullIcon,0); f.strokeColor=color.black; } function executePostGameEffects() { sortoutDPS(); var fL = this.getField("MemLbutton.1"); var fR = this.getField("MemRbutton.1"); var LulCorner = fL.rect; var RulCorner = fR.rect; var mWidth = LulCorner[2]-LulCorner[0]; var mHeight = LulCorner[1]-LulCorner[3]; var nCnt = 0; for ( var i=0; i