aboutsummaryrefslogtreecommitdiffstats
path: root/SNPGUI.sc
diff options
context:
space:
mode:
authorDavid Runge <dave@sleepmap.de>2015-03-30 01:34:11 +0200
committerDavid Runge <dave@sleepmap.de>2015-03-30 01:34:11 +0200
commit42519292ff9f4c23ca9b1b63d76c39997e10123a (patch)
tree566f3661babbfe5ae308bd44ffa666033bbea418 /SNPGUI.sc
parenta8ac0764f50f2dc9391754a1f9f29f41f7289523 (diff)
downloadthesoundofpeople-42519292ff9f4c23ca9b1b63d76c39997e10123a.tar.gz
thesoundofpeople-42519292ff9f4c23ca9b1b63d76c39997e10123a.tar.bz2
thesoundofpeople-42519292ff9f4c23ca9b1b63d76c39997e10123a.tar.xz
thesoundofpeople-42519292ff9f4c23ca9b1b63d76c39997e10123a.zip
SNPGUI.sc: Modularizing and renaming functionality.\ Adding multi-color support, fade out functionality for SNP texts.\ Changing fonts and sizes.\ Fixing positions of speakerViews on all available speaker setups.\ Renaming functions and variables to more readable names.
Diffstat (limited to 'SNPGUI.sc')
-rw-r--r--SNPGUI.sc323
1 files changed, 215 insertions, 108 deletions
diff --git a/SNPGUI.sc b/SNPGUI.sc
index 8121af2..3027d81 100644
--- a/SNPGUI.sc
+++ b/SNPGUI.sc
@@ -2,18 +2,25 @@ SNPGUI {
var <speakerSetup;//Array holding the chromosome numbers for each speaker
var <mainView;// main view object
+ var <speakerView;// main view object
var <drawView;// main view object
var <speakerDict;//Dictionary of Views (per speaker)
var <textDict;//Dictionary of StaticText obbjects
- var <taskSNP;//task for updating the SNP texts of chromosomes
- var <snpDict; //Dictionary of texts for SNPs on chromosomes (replaceable)
+ var <updateSNPTextTask;//task for updating the SNP texts of chromosomes
+ var <snpTextFadeTasks; //Dictionary of tasks for SNP texts
+ 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 <intermediateTextDict; //Dictionary of texts for SNPs on chromosomes (intermediate)
var <arcRadius = 200;//size of the arc, surrounded by speakers
var <radiusOffset = 75;//size of the arc, surrounded by speakers
var <mainWidth = 800;
var <mainHeight = 800;
- var <speakerHeight = 50;
- var <speakerWidth = 50;
- var <lineHeight = 12;
+ var <speakerHeight = 70;
+ var <speakerWidth = 70;
+ var <lineHeight = 16;
+ var <defaultFont = "Monaco";
*new{
arg setup;
@@ -22,154 +29,254 @@ SNPGUI {
snpGUIInit{
arg setup;
- setup.size.postln;
speakerSetup = setup;
- this.setupViews(setup.size);
- //create a dictionary the size of the setup
+ this.createDicts;
+ this.createViews;
+ this.createTasks;
}
+
// initialize Dictionaries for all things
- initDicts{
- arg setup;
- speakerDict = Dictionary.new(setup.size+1);
- //textDict = Dictionary.new(setup.size);
- textDict = Dictionary.new(25);//Dictionary holding all StaticText objects that can be modified
- snpDict = Dictionary.new(25);
- //taskDict = Dictionary.new(25);
- //add each speaker number
- setup.do({|speaker,i|
- var tmp = Dictionary.new(setup[0].size);
+ createDicts{
+ speakerDict = Dictionary.new(speakerSetup.size+1);
+ intermediateTextDict = Dictionary.new(SNPInfo.chromosomesLength.size.asInt); // Dictionary of intermediate Strings to be used for the StaticText objects in textDict
+ textDict = Dictionary.new(SNPInfo.chromosomesLength.size.asInt);//Dictionary holding all StaticText objects that can be modified
+ }
+
+ // creates all Views
+ createViews{
+ this.createMainView;
+// this.createDrawView;
+ this.createSpeakerViews;
+ }
+
+ // create the main View (the main window)
+ createMainView{
+ mainView = View.new();
+ mainView.minSize = mainWidth@mainHeight;
+ mainView.userCanClose = true;
+ mainView.enabled = true;
+ mainView.visible = true;
+ mainView.name = "The Sound Of People";
+ mainView.background = Color.fromHexString("#DBDBDB");
+ mainView.onResize = {
+ if((drawView.notNil), {
+ drawView.moveTo((mainView.absoluteBounds.width/2)-(drawView.bounds.width/2), (mainView.absoluteBounds.height/2)-(drawView.bounds.height/2));
+ });
+ speakerView.moveTo((mainView.absoluteBounds.width/2)-(speakerView.bounds.width/2), (mainView.absoluteBounds.height/2)-(speakerView.bounds.height/2));
+ };
+ }
+
+ //creates a UserView, draws a circle
+ createDrawView{
+ drawView = UserView.new(mainView, Rect(0, 0, mainView.bounds.width, mainView.bounds.height));
+ drawView.minSize = mainWidth@mainHeight;
+ drawView.background = Color.fromHexString("#DBDBDB");
+ drawView.background = Color.fromHexString("#e7ebe7");
+ // center to mid of mainView on resize
+ drawView.onResize = { drawView.moveTo(mainView.bounds.width/2-drawView.bounds.width/2, mainView.bounds.height/2-drawView.bounds.height/2)};
+ // draw a circle
+ drawView.drawFunc = {
+ Pen.translate(drawView.bounds.width/2, drawView.bounds.height/2);
+ Pen.strokeColor = Color.black;
+ Pen.color = Color.black;
+ Pen.addArc(0@0, arcRadius, 0, 2pi);
+ Pen.stroke;
+ };
+ }
+
+ // creates all speakerViews necessary for the setup defined in speakerSetup
+ createSpeakerViews{
+ speakerView = View.new(
+ mainView,
+ Rect(
+ 0,
+ 0,
+ mainWidth,
+ mainHeight
+ )
+ );
+ speakerView.minSize = mainWidth@mainHeight;
+ // create a speakerView for each speaker in the setup
+ speakerSetup.do({|speaker,i|
// Adds a View with speaker information to the speakerDict
- speakerDict.add((i+1).asSymbol -> this.initSpeakerView(i, setup.size, setup[0].size));
+ speakerDict.add((i+1).asSymbol -> 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
- //tmp.add(chromosome.asSymbol -> this.initChromosomeText(chromosome.asSymbol, (i+1).asSymbol, j+1));
- textDict.add(chromosome.asSymbol -> this.initChromosomeText(chromosome.asSymbol, (i+1).asSymbol, j+1));
- snpDict.add(chromosome.asSymbol -> "");
+ textDict.add(chromosome.asSymbol -> this.createChromosomeTexts(chromosome.asSymbol, (i+1).asSymbol, j));
+ intermediateTextDict.add(chromosome.asSymbol -> "");
});
- //textDict.add((i+1).asSymbol -> tmp);
});
// Adds a View for MT chromosome with speaker information to the speakerDict
- speakerDict.add(\all -> this.initSpeakerView(-1, setup.size, 1));
+ speakerDict.add(\all -> this.createSpeakerView(-1, speakerSetup.size, 1));
// add chromosome text for MT to the speaker called all
- textDict.add(\25 -> this.initChromosomeText(\25, \all, 1));
- //
- snpDict.add(25.asSymbol -> "");
- //start a Task to update the SNP currently playing
- this.startSNPTask;
- //snpDict.postln;
- //speakerDict.postln;
- //textDict.postln;
- }
-
- //init a StaticText for a chromosome in its speaker View, returns its replaceable component (for SNPs)
- initChromosomeText{
- arg chromosome, number, position;
- var snpText, chromosomeText;
- chromosomeText = StaticText.new(speakerDict.at(number), Rect(0, lineHeight*position, (speakerDict.at(number).bounds.width/2), lineHeight));
- chromosomeText.string = (chromosome.asString++": ");
- chromosomeText.align = \left;
- snpText = StaticText.new(speakerDict.at(number), Rect((speakerDict.at(number).bounds.width/2), lineHeight*position, (speakerDict.at(number).bounds.width/2), lineHeight));
- snpText.string = "Test";
- snpText.align = \right;
- ^snpText;
+ textDict.add(SNPInfo.chromosomesLength.size.asSymbol -> this.createChromosomeTexts(SNPInfo.chromosomesLength.size.asSymbol, \all, 0));
+ intermediateTextDict.add(SNPInfo.chromosomesLength.size.asSymbol -> "");
}
- //inits a View for one speaker, adds its name as StaticText object and returns itself
- initSpeakerView{
- arg number, total, perSpeaker;
- var mid, radius, radianOffset, radian, x, y, speakerContainer, text;
- mid = Point.new(mainWidth/2,mainHeight/2);//mid of the circle
+ //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/total*number;//segment of the circle the speaker is placed in
+ 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 View container for a speaker
- speakerContainer = View.new(drawView, Rect(x, y, speakerWidth, (perSpeaker+1)*lineHeight));
+ //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.green;
+ 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");
- // adding the speaker number
- text = StaticText(speakerContainer, Rect(0, 0, speakerContainer.bounds.width, lineHeight));
- text.string = (number+1).asString;
- text.align = \center;
+ // 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 = 360/total*0;
- //Calculating x and y coordinates for the View to be created
+ 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);
- text.string = "all";
});
-// ("Speaker: "++number.asString).postln;
-// ("cos("++radian.asString++"): "++cos(degrad(radian)).asString).postln;
-// ("sin("++radian.asString++"): "++sin(degrad(radian)).asString).postln;
^speakerContainer;
}
- /*
- * Setup the initial window and all of its StaticText elements
- */
- setupViews{
- arg numChannels;
- mainView = View.new(nil,Rect(50,50,mainWidth,mainHeight));
- //mainView.front;
- mainView.fixedSize=mainWidth@mainHeight;
- mainView.enabled = true;
- mainView.userCanClose = true;
- mainView.alwaysOnTop;
- mainView.visible = true;
- mainView.name = "The Sound Of People";
- mainView.background = Color.white;
- mainView.bounds.postln;
- //make a UserView for drawing with Pen
- drawView = UserView.new(mainView, Rect(0, 0, mainView.bounds.width, mainView.bounds.height));
- drawView.animate = true;
- drawView.frameRate = 60.0;
- // draw a circle
- drawView.drawFunc = {
- Pen.translate(drawView.bounds.width/2, drawView.bounds.height/2);
- Pen.strokeColor = Color.black;
- Pen.color = Color.black;
- Pen.addArc(0@0, arcRadius, 0, 2pi);
- Pen.stroke;
- };
- //add StaticText objects for names of speakers, names of chromosomes and names of SNPs
- this.initDicts(speakerSetup);
+ //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
- startSNPTask{
- taskSNP = Task.new({
+ createUpdateSNPTextTask{
+ updateSNPTextTask = Task.new({
{
//get all values from the dictionary and update the corresponding StaticText objects
- snpDict.keysValuesDo({|key, value|
- textDict.at(key.asSymbol).string_(value.asString);
+ 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;
});
- taskSNP.play(AppClock);
+ updateSNPTextTask.play(AppClock);
}
//set the text of a specific chromosome (aka.: which SNP is currently playing?)
- setSNPText{
+ setIntermediateText{
arg chromosome, text;
- //delete all strings first
-// snpDict.keysValuesChange{|key,value|
-// ^"";
-// };
- //add the current SNP text to the dictionary
- snpDict.put(chromosome.asSymbol, text.asString);
+ intermediateTextDict.put(chromosome.asSymbol, text.asString);
}
+
// get the current SNP text of a chromosome
- getSNPText{
+ getIntermediateText{
arg chromosome;
- var text = snpDict.at(chromosome.asSymbol);
+ var text = intermediateTextDict.at(chromosome.asSymbol);
^text;
}
}