package org.onebillion.onecourse.mainui.oc_lettersandsounds; import android.graphics.Color; import android.graphics.PointF; import android.graphics.RectF; import android.graphics.Typeface; import android.view.View; import org.onebillion.onecourse.controls.OBControl; import org.onebillion.onecourse.controls.OBImage; import org.onebillion.onecourse.controls.OBLabel; import org.onebillion.onecourse.controls.OBPath; import org.onebillion.onecourse.utils.OBAnim; import org.onebillion.onecourse.utils.OBAnimationGroup; import org.onebillion.onecourse.utils.OBConditionLock; import org.onebillion.onecourse.utils.OBImageManager; import org.onebillion.onecourse.utils.OBPhoneme; import org.onebillion.onecourse.utils.OBUtils; import org.onebillion.onecourse.utils.OBWord; import org.onebillion.onecourse.utils.OB_Maths; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Map; /** * Created by alan on 08/08/16. */ public class OC_Wm1 extends OC_Wordcontroller { public final static int MSE_DN = 0, MSE_UP = 1; Map<String,OBPhoneme> wordDict; List<List>wordSets; OBPath wordLine,wordsRect; float picScale; PointF picPosition,dashTargetPosition; String currWordID; int textColour; List<OBLabel> labels = new ArrayList<>(); float textSize; OBConditionLock finishLock; public void miscSetUp() { textSize = applyGraphicScale(Float.parseFloat(eventAttributes.get("textsize"))); wordDict = OBUtils.LoadWordComponentsXML(true); String ws = parameters.get("words"); String[] wss = ws.split(";"); wordSets = new ArrayList<>(); for(String w : wss) wordSets.add(Arrays.asList(w.split(","))); currNo = 0; OBPath textswatch = (OBPath) objectDict.get("textswatch"); textColour = textswatch.fillColor(); needDemo = parameters.get("demo") != null && parameters.get("demo").equals("true"); OBControl pic = objectDict.get("pic"); picScale = pic.scale(); picPosition = pic.position(); deleteControls("pic"); wordsRect = (OBPath) objectDict.get("wordsrect"); wordLine = (OBPath) objectDict.get("wordline"); wordLine.sizeToBoundingBoxIncludingStroke(); dashTargetPosition = new PointF(); finishLock = new OBConditionLock(); } public void prepare() { super.prepare(); loadFingers(); loadEvent("mastera"); miscSetUp(); events = new ArrayList<>(); if(needDemo) events.add("b"); events.addAll(Arrays.asList("c,d,e".split(","))); while(events.size() > wordSets.size()) events.remove(events.size()-1); while(events.size() < wordSets.size()) events.add(events.get(events.size()-1)); events.add(0,"a"); doVisual(currentEvent()); } public OBLabel setUpLabel(String tx) { Typeface tf = OBUtils.standardTypeFace(); OBLabel label = new OBLabel(tx,tf,textSize); label.setColour(Color.BLACK); return label; } public void distributeLabels(List<OBLabel>labs,RectF r) { int gaps = labs.size() + 1; float gap = r.height(); for(OBLabel l : labs) gap -= l.height(); gap = gap / gaps; float y = r.top + gap; for(OBLabel l : labs) { l.setTop(y); y = l.bottom(); y += gap; } float maxwidth = 0; for(OBLabel l : labs) if(l.width() > maxwidth) maxwidth = l.width(); gap = r.width() - maxwidth; float lmargin = r.left + gap / 2; for(OBLabel l : labs) { l.setLeft(lmargin); l.setZPosition(10); l.setColour(textColour); attachControl(l); l.hide(); l.setProperty("origpos",new PointF(l.position().x,l.position().y)); } } public void setScenea() { } public void setSceneXX(String scene) { for(OBControl c : labels) detachControl(c); deleteControls("pic"); List<String>warr = wordSets.get(currNo); currWordID = warr.get(0); OBWord orw = (OBWord) wordDict.get(currWordID); OBImage im = OBImageManager.sharedImageManager().imageForName(orw.imageName); im.setScale(picScale); im.setPosition(picPosition); objectDict.put("pic",im); attachControl(im); im.setRight(-1); List labs = new ArrayList<>(); for(String wid : warr) { OBWord rw = (OBWord) wordDict.get(wid); labs.add(setUpLabel(rw.text)); } distributeLabels(OBUtils.randomlySortedArray(labs),wordsRect.frame()); labels = labs; if(dashTargetPosition.equals(new PointF())) { float h = baselineOffsetForText("My",OBUtils.standardTypeFace(),textSize); dashTargetPosition = new PointF(wordLine.position().x,wordLine.position().y); RectF b = boundingBoxForText("My",OBUtils.standardTypeFace(),textSize); dashTargetPosition.y -= (h - b.height() / 2 + applyGraphicScale(12)); } targets = (List<OBControl>)(Object)labels; } public void showStuff() throws Exception { waitForSecs(0.3f); playSfxAudio("slideon",false); moveObjects(Arrays.asList(objectDict.get("pic")),picPosition,-1,OBAnim.ANIM_EASE_OUT); playSfxAudio("wordson",false); List<OBLabel>labs = new ArrayList<>(labels); Collections.sort(labs, new Comparator<OBLabel>() { @Override public int compare (OBLabel obj1, OBLabel obj2) { if(obj1.position().y < obj2.position().y) return -1; if(obj1.position().y > obj2.position().y) return 1; return 0; } }); for(OBLabel lab : labs) { lab.show(); waitForSecs(0.2f); } waitSFX(); } public void demoa() throws Exception { waitForSecs(0.3f); playAudioQueuedScene("DEMO",true); waitForSecs(0.3f); nextScene(); } public void highlightDash(boolean high) { int col = high?Color.RED :Color.BLACK; wordLine.setStrokeColor(col); } public void doMainXX() throws Exception { showStuff(); waitForSecs(0.2f); setReplayAudio((List<Object>)(Object)currentAudio("PROMPT.REPEAT")); List audio = currentAudio("PROMPT"); if(audio != null) playAudioQueued(OBUtils.insertAudioInterval(audio,300),false); } public void doMainc() throws Exception { showStuff(); waitForSecs(0.2f); setReplayAudio((List<Object>)(Object)currentAudio("PROMPT.REPEAT")); PointF destpt = OB_Maths.locationForRect(0.5f, 1.1f, wordsRect.frame); PointF startpt = pointForDestPoint(destpt,15); loadPointerStartPoint(startpt,destpt); movePointerToPoint(destpt,-0.8f,true); playAudioScene("PROMPT",0,true); movePointerToPoint(OB_Maths.locationForRect(0.5f, 1.1f, wordLine.frame),-1,true); playAudioScene("PROMPT",1,true); thePointer.hide(); } public void endBody() { List reminderAudio = currentAudio("PROMPT.REMINDER"); if(reminderAudio != null) { try { long sttime = statusTime; waitForSecs(0.3f); waitAudio(); if(sttime == statusTime) reprompt(sttime,reminderAudio,6); } catch(Exception e) { } } } public void placeLabel(OBLabel label) throws Exception { moveObjects(Arrays.asList((OBControl)label),dashTargetPosition,-0.8f,OBAnim.ANIM_EASE_IN_EASE_OUT); waitForSecs(0.1f); highlightDash(true); playSfxAudio("wordonline",true); } public void clearOff() throws Exception { playSfxAudio("bigoff",false); lockScreen(); for(OBControl c : labels) detachControl(c); deleteControls("pic"); highlightDash(false); wordLine.setOpacity(1); unlockScreen(); waitForSecs(0.1f); waitSFX(); } public void demob() throws Exception { showStuff(); waitForSecs(0.3f); PointF destpt = OB_Maths.locationForRect(0.6f, 0.8f, labels.get(0).frame()); PointF startpt = pointForDestPoint(destpt,15); loadPointerStartPoint(startpt,destpt); movePointerForwards(applyGraphicScale(80),-1); playAudioScene("DEMO2",0,true); waitForSecs(0.3f); movePointerToPoint(destpt,-0.8f,true); waitForSecs(0.3f); List<OBControl> lst = Arrays.asList(labels.get(0),thePointer); moveObjects(lst,dashTargetPosition,-0.8f,OBAnim.ANIM_EASE_IN_EASE_OUT); waitForSecs(0.1f); highlightDash(true); playSfxAudio("wordonline",false); movePointerForwards(applyGraphicScale(-80),-1); OBAnimationGroup.runAnims(Arrays.asList( OBAnim.opacityAnim(0.0f,wordLine) , OBAnim.scaleAnim(1.3f,labels.get(0)) , OBAnim.colourAnim("colour",Color.BLACK,labels.get(0)) , OBAnim.opacityAnim(0.4f,labels.get(1)) , OBAnim.opacityAnim(0.4f,labels.get(2))), 0.6f,true,OBAnim.ANIM_EASE_IN_EASE_OUT,this); waitForSecs(0.3f); highlightLabel(labels.get(0),true); playAudioQueued(Arrays.asList((Object)currWordID) ,true); highlightLabel(labels.get(0),false); waitForSecs(0.7f); thePointer.hide(); waitForSecs(0.3f); playAudioScene("DEMO2",1,true); waitForSecs(0.3f); nextScene(); } public void nextScene() { if(++eventIndex >= events.size() ) OBUtils.runOnOtherThread(new OBUtils.RunLambda() { public void run() throws Exception { fin(); } }); else OBUtils.runOnOtherThread(new OBUtils.RunLambda() { public void run() throws Exception { try { if(labels.size() > 0) { clearOff(); currNo++; } } catch(Exception exception) { } setScene(events.get(eventIndex)); } }); } public void goHome() { OBUtils.runOnOtherThread(new OBUtils.RunLambda() { public void run() throws Exception { PointF pt = (PointF) target.propertyValue("origpos"); moveObjects(Arrays.asList(target),pt,-2,OBAnim.ANIM_EASE_IN_EASE_OUT); switchStatus(currentEvent()); target = null; } }); } public void stage2Check() { finishLock.lockWhenCondition(MSE_UP); finishLock.unlock(); if(target == labels.get(0)) { try { OBAnimationGroup.runAnims(Arrays.asList( OBAnim.opacityAnim(0.0f,wordLine) , OBAnim.scaleAnim(1.3f,labels.get(0)) , OBAnim.colourAnim("colour",Color.BLACK,labels.get(0)) , OBAnim.opacityAnim(0.4f,labels.get(1)) , OBAnim.opacityAnim(0.4f,labels.get(2))), 0.6f,true,OBAnim.ANIM_EASE_IN_EASE_OUT,this); waitForSecs(0.3f); highlightLabel(labels.get(0),true); playAudioQueued(Arrays.asList((Object)currWordID) ,true); highlightLabel(labels.get(0),false); waitForSecs(0.3f); gotItRightBigTick(true); waitForSecs(0.7f); nextScene(); } catch(Exception e) { } } else { gotItWrongWithSfx(); highlightDash(false); goHome(); } } public void touchUpAtPoint(PointF pt,View v) { finishLock.lock(); finishLock.unlockWithCondition(MSE_UP); if(status() == STATUS_DRAGGING) { setStatus(STATUS_CHECKING); RectF r = new RectF(wordLine.frame); RectF tr = new RectF(target.frame); r.top -= tr.height(); if(r.intersect(tr)) { OBUtils.runOnOtherThread(new OBUtils.RunLambda() { public void run() throws Exception { placeLabel((OBLabel)target); stage2Check(); } }); } else { goHome(); } return; } } public void touchMovedToPoint(PointF pt,View v) { if(status() == STATUS_DRAGGING) { PointF newpos = OB_Maths.AddPoints(pt, dragOffset); target.setPosition(newpos); if(target.frame.contains(wordLine.position().x, wordLine.position().y)) { setStatus(STATUS_CHECKING); OBUtils.runOnOtherThread(new OBUtils.RunLambda() { public void run() throws Exception { try { placeLabel((OBLabel)target); stage2Check(); } catch(Exception exception) { } } }); } } } public void checkTarget(OBControl targ,PointF pt) { setStatus(STATUS_DRAGGING); targ.setZPosition(13); dragOffset = OB_Maths.DiffPoints(targ.position(), pt); finishLock.lock(); finishLock.unlockWithCondition(MSE_DN); } public void touchDownAtPoint(final PointF pt,View v) { if(status() == STATUS_AWAITING_CLICK) { target = (OBControl) findTarget(pt); if(target != null) { OBUtils.runOnOtherThread(new OBUtils.RunLambda() { public void run() throws Exception { checkTarget(target,pt); } }); } } } }