SNPGUI { var textFadeTime = 0.5; // time (in seconds) it takes for a SNP text to fade out var <>textFadeSteps = 20; // amount of steps within textFadeTime in which to blend the color of a SNP text var <>speakerViewMargin = 4; // the margin between speakerView border and a text within it var <>speakerViewHeadMargin = 24; // the margin reserved for the speaker name var this.createSpeakerView(i, speakerSetup.size, speakerSetup[0].size)); // iterate all chromosome information from original setup speaker.do({|chromosome, j| //add chromosome number -> replaceable SNP StaticText object to temporary Dictionary textDict.add(chromosome.asSymbol -> this.createChromosomeTexts(chromosome.asSymbol, (i+1).asSymbol, j)); intermediateTextDict.add(chromosome.asSymbol -> ""); }); }); // Adds a View for MT chromosome with speaker information to the speakerDict speakerDict.add(\all -> this.createSpeakerView(-1, speakerSetup.size, 1)); // add chromosome text for MT to the speaker called all textDict.add(SNPInfo.chromosomesLength.size.asSymbol -> this.createChromosomeTexts(SNPInfo.chromosomesLength.size.asSymbol, \all, 0)); intermediateTextDict.add(SNPInfo.chromosomesLength.size.asSymbol -> ""); } //creates a View for one speaker, adds its name as StaticText object and returns itself createSpeakerView{ arg number, total, chromosomesOnSpeaker; var mid, radius, radianOffset, radian, x, y, speakerContainer, speakerContainerInner, speakerText; mid = Point.new((mainWidth/2)-(speakerWidth/2),(mainHeight/2)-(speakerHeight/2));//mid of the circle radius = arcRadius+radiusOffset;//make a slightly bigger radius for the text objects radianOffset = 360/(total*2);// radian offset used to make speaker 1 be positioned front left radian = (360*(number/total))-90;//segment of the circle the speaker is placed in //Calculating x and y coordinates for the View to be created x = mid.x+(radius*cos(degrad(radian-radianOffset))); y = mid.y+(radius*sin(degrad(radian-radianOffset))); //setting up the border for a speaker speakerContainer = View.new( speakerView, Rect( x, y, speakerWidth, ((chromosomesOnSpeaker)*lineHeight)+(speakerViewMargin*2)+speakerViewHeadMargin ) ); speakerContainer.visible = true; speakerContainer.background = Color.fromHexString("#7f7f7f"); //setting up the View container for a speaker speakerContainerInner = View.new( speakerContainer, Rect( (speakerViewMargin/2), (speakerViewMargin/2), speakerWidth-speakerViewMargin, ((chromosomesOnSpeaker)*lineHeight)+speakerViewMargin+speakerViewHeadMargin ) ); speakerContainerInner.visible = true; speakerContainerInner.background = Color.fromHexString("#EEEEEE"); // add the speaker text (number of the speaker) speakerText = StaticText( speakerContainerInner, Rect( 0, speakerViewMargin, speakerContainer.bounds.width, lineHeight ) ); speakerText.align = \center; speakerText.string = (number+1).asString; speakerText.stringColor = Color.fromHexString("#4A52C4"); speakerText.font = Font(this.defaultFont,16,true); //add exception for no/ all speaker if(number<0,{ // rename the speaker speakerText.string = "all"; //recalculate radius and offset radius = radius+radiusOffset; radian = -90+((360/total)/2); //recalculate x and y coordinates to move the View x = mid.x+(radius*cos(degrad(radian-radianOffset))); y = mid.y+(radius*sin(degrad(radian-radianOffset))); // move speakerContainer to new coordinates (top center) speakerContainer.moveTo(x, y); }); ^speakerContainer; } //create a StaticText for a chromosome in its speaker View, returns its replaceable component (for SNPs) createChromosomeTexts{ arg chromosome, number, position; var snpText, chromosomeText; //create the name of the chromosome as StaticText chromosomeText = StaticText.new( speakerDict.at(number), Rect( speakerViewMargin, (lineHeight*position)+speakerViewHeadMargin, (speakerDict.at(number).bounds.width/2), lineHeight ) ); chromosomeText.align = \left; chromosomeText.string = if((chromosome.asInt < 10), {("0"++chromosome.asString++": ")}, {chromosome.asString++": "}); chromosomeText.font = Font(this.defaultFont,13,true,true); //create the snpText (its string will be set with a Task later) snpText = StaticText.new( speakerDict.at(number), Rect(( speakerDict.at(number).bounds.width/2)-speakerViewMargin, (lineHeight*position)+speakerViewHeadMargin, (speakerDict.at(number).bounds.width/2), lineHeight ) ); snpText.align = \right; snpText.string = ""; snpText.font = Font(this.defaultFont,13,true); ^snpText; } //create all Tasks createTasks{ this.createSNPTextFadeTasks(SNPInfo.chromosomesLength.size.asInt); this.createUpdateSNPTextTask; } // create Tasks to fade out the text of all SNPs and blend its color gradually createSNPTextFadeTasks{|size| snpTextFadeTasks = Dictionary.new(size); size.do({|item,i| var textTask; snpTextFadeTasks.put((i+1).asSymbol, textTask = Task({ var snp = (i+1).asSymbol; var elapsed = 0.0; // reset the intermediateTextDict text this.setIntermediateText(snp, ""); // blend the original color of the chromosome's SNP by the amount of steps defined in textFadeSteps with black. Each step's length is defined by textFadeTime this.textFadeSteps.do({|item,i| textDict.at(snp.asSymbol).alpha_(textDict.at(snp.asSymbol).alpha-(textFadeTime/this.textFadeSteps)); textDict.at(snp.asSymbol).stringColor_(textDict.at(snp.asSymbol).stringColor.blend(Color.black(), textFadeTime/this.textFadeSteps)); (textFadeTime/this.textFadeSteps).wait; }); textDict.at(snp.asSymbol).string_(""); }) ); }); } //Starts a task to update texts for SNP of chromosomes on AppClock createUpdateSNPTextTask{ updateSNPTextTask = Task.new({ { //get all values from the dictionary and update the corresponding StaticText objects intermediateTextDict.keysValuesDo({|key, value| if((value.asString != ""),{ //set the text and color for the SNP here,as doing this within the fade Task would delay it too much textDict.at(key.asSymbol).string_(value.asString); // set different color for each base/ combination of bases textDict.at(key.asSymbol).stringColor_(Color.fromHexString(SNPInfo.getColorFromBase(value.asString))); //start or reset the snpTextTask belonging to this chromosome (to fade out its text) if((snpTextFadeTasks.at(key.asSymbol).isPlaying), { snpTextFadeTasks.at(key.asSymbol).reset; },{ snpTextFadeTasks.at(key.asSymbol).start(AppClock); }); }); }); 0.02.wait; }.loop; }); updateSNPTextTask.play(AppClock); } //set the text of a specific chromosome (aka.: which SNP is currently playing?) setIntermediateText{ arg chromosome, text; intermediateTextDict.put(chromosome.asSymbol, text.asString); } // get the current SNP text of a chromosome getIntermediateText{ arg chromosome; var text = intermediateTextDict.at(chromosome.asSymbol); ^text; } }