Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPootle daemon <pootle@pootle.sugarlabs.org>2013-07-03 04:32:09 (GMT)
committer Pootle daemon <pootle@pootle.sugarlabs.org>2013-07-03 04:32:09 (GMT)
commitdff011ab3a5c2a59a994999a3185a5604e00407d (patch)
tree493b00d43d587d9bb63898c4904bc30924d5e2f9
parent8071c0d0d11c5f84f39dfbdd8404b012be70ecb9 (diff)
parent110460501d37275af983fc045f9be3b860370fd3 (diff)
Merge branch 'master' of git.sugarlabs.org:measure/mainline
-rw-r--r--config.py1
-rw-r--r--icons/instruments.svg158
-rw-r--r--icons/notes.svg47
-rw-r--r--icons/octaves.svg37
-rw-r--r--measure.py7
-rw-r--r--sensor_toolbar.py50
-rw-r--r--tuning_toolbar.py333
7 files changed, 495 insertions, 138 deletions
diff --git a/config.py b/config.py
index 8a4c22c..f952b7a 100644
--- a/config.py
+++ b/config.py
@@ -73,6 +73,7 @@ UPPER = 4.0
# TRANS: Please use short versions of instrument names if possible
INSTRUMENT_DICT = {
+ _('None'): [],
_('Guitar'): [82.4069, 110, 146.832, 195.998, 246.942, 329.628],
_('Violin'): [195.998, 293.665, 440, 659.255],
_('Viola'): [130.813, 195.998, 293.665, 440],
diff --git a/icons/instruments.svg b/icons/instruments.svg
new file mode 100644
index 0000000..32466ee
--- /dev/null
+++ b/icons/instruments.svg
@@ -0,0 +1,158 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ version="1.1"
+ width="55"
+ height="55"
+ viewBox="0 0 55 55"
+ id="Layer_1"
+ xml:space="preserve"><metadata
+ id="metadata68"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
+ id="defs66" /><path
+ d="m 4.455,25.83 h 23.59 c 0.512,0 0.929,0.417 0.929,0.931 v 1.568 c 0,0.512 -0.417,0.93 -0.929,0.93 H 4.455 c -0.515,0 -0.931,-0.417 -0.931,-0.93 v -1.566 c 0,-0.516 0.415,-0.933 0.931,-0.933 z"
+ id="path8"
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" /><rect
+ width="21.995001"
+ height="14.687"
+ x="5.25"
+ y="29.259001"
+ id="rect10"
+ style="fill:#000000;fill-opacity:1;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" /><path
+ d="m 4.455,43.945 h 23.59 c 0.512,0 0.929,0.416 0.929,0.932 v 1.566 c 0,0.515 -0.417,0.934 -0.929,0.934 H 4.455 c -0.515,0 -0.931,-0.417 -0.931,-0.934 v -1.566 c 0,-0.512 0.415,-0.932 0.931,-0.932 z"
+ id="path17"
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" /><path
+ d="m 5.25,43.945 5.671,-14.687 5.241,14.685 5.26,-14.685"
+ id="path19"
+ style="fill:#000000;fill-opacity:1;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" /><path
+ d="M 27.242,43.945 21.422,29.258"
+ id="path21"
+ style="fill:#000000;fill-opacity:1;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" /><line
+ id="line27"
+ fill="none"
+ stroke="#010101"
+ stroke-width="2"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ x1="20.305"
+ y1="22.694"
+ x2="29.118999"
+ y2="18.362"
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" /><line
+ id="line29"
+ fill="none"
+ stroke="#010101"
+ stroke-width="2"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ x1="3.668"
+ y1="16.114"
+ x2="12.464"
+ y2="20.487"
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" /><path
+ d="m 15.51,20.681 c 0.331,0.873 -0.103,1.845 -0.968,2.173 -0.864,0.328 -1.834,-0.113 -2.165,-0.986 -0.33,-0.872 0.104,-1.845 0.968,-2.173 0.865,-0.327 1.835,0.114 2.165,0.986 z"
+ id="path23"
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" /><path
+ d="m 20.094,24.676 c -0.626,0.677 -1.684,0.715 -2.364,0.086 -0.679,-0.627 -0.721,-1.686 -0.094,-2.362 0.626,-0.678 1.685,-0.717 2.363,-0.088 0.68,0.629 0.722,1.687 0.095,2.364 z"
+ id="path25"
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" /><path
+ d="M 29.604,26.749"
+ id="path14"
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" /><path
+ d="M 29.266,9.782"
+ id="path16"
+ style="fill:none;stroke:#010101;stroke-width:2;stroke-linecap:round;stroke-linejoin:round" /><g
+ id="g18"
+ style="fill:#000000;fill-opacity:1;stroke:#ffffff;stroke-opacity:1"><g
+ id="XMLID_1_"
+ style="fill:#000000;fill-opacity:1;stroke:#ffffff;stroke-opacity:1"><g
+ id="g21"
+ style="fill:#000000;fill-opacity:1;stroke:#ffffff;stroke-opacity:1"><path
+ d="m 24.533,14.555 -7.044,4.876 -0.082,-14.038 7.126,5.772 c 0,0.021 0.397,0.305 20.951,0.631 v 2.545 l -20.951,0.214 z"
+ id="path24"
+ style="fill:#000000;fill-opacity:1;stroke:#ffffff;stroke-opacity:1" /></g><g
+ id="g26"
+ style="fill:#000000;fill-opacity:1;stroke:#ffffff;stroke-opacity:1"><path
+ d="M 45.483,11.796 C 24.929,11.47 24.532,11.186 24.532,11.165 l -7.126,-5.772 0.082,14.038 7.044,-4.876 20.951,-0.213 v -2.546 z"
+ id="path28"
+ style="fill:#000000;fill-opacity:1;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" /></g></g><line
+ fill="none"
+ stroke="#010101"
+ stroke-width="2"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ x1="36.449001"
+ y1="8.2370005"
+ x2="36.449001"
+ y2="11.291"
+ id="line30"
+ style="fill:#000000;fill-opacity:1;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" /><line
+ fill="none"
+ stroke="#010101"
+ stroke-width="2"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ x1="33.521"
+ y1="8.2370005"
+ x2="33.521"
+ y2="11.291"
+ id="line32"
+ style="fill:#000000;fill-opacity:1;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" /><line
+ fill="none"
+ stroke="#010101"
+ stroke-width="2"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ x1="30.466999"
+ y1="8.2370005"
+ x2="30.466999"
+ y2="11.291"
+ id="line34"
+ style="fill:#000000;fill-opacity:1;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" /></g><path
+ d="M 43.051,6.261"
+ id="path36"
+ style="fill:none;stroke:#010101;stroke-width:2;stroke-linecap:round;stroke-linejoin:round" /><path
+ d="M 40.778,25.476"
+ id="path38"
+ style="fill:none;stroke:#010101;stroke-width:2;stroke-linecap:round;stroke-linejoin:round" /><g
+ id="g40"
+ style="fill:#000000;fill-opacity:1;stroke:#ffffff;stroke-opacity:1"><g
+ id="XMLID_3_"
+ style="fill:#000000;fill-opacity:1;stroke:#ffffff;stroke-opacity:1"><g
+ id="g43"
+ style="fill:#000000;fill-opacity:1;stroke:#ffffff;stroke-opacity:1"><path
+ d="m 47.486,42.039 c 0.626,6.335 -6.97,6.215 -6.97,6.215 h -0.068 c 0,0 -7.604,0.12 -6.97,-6.215 0.111,-1.071 2.041,-1.929 2.041,-1.929 0,0 0.856,-1.604 0.103,-3.644 L 34.336,33.14 c 0,0 -0.643,-5.247 5.684,-5.247 h 0.926 c 6.318,0 5.684,5.247 5.684,5.247 l -1.285,3.326 c -0.755,2.04 0.103,3.644 0.103,3.644 0,0 1.927,0.858 2.038,1.929 z"
+ id="path45"
+ style="fill:#000000;fill-opacity:1;stroke:#ffffff;stroke-opacity:1" /></g><g
+ id="g47"
+ style="fill:#000000;fill-opacity:1;stroke:#ffffff;stroke-opacity:1"><path
+ d="m 40.945,27.894 c 6.318,0 5.684,5.247 5.684,5.247 l -1.285,3.326 c -0.755,2.04 0.103,3.644 0.103,3.644 0,0 1.929,0.857 2.04,1.929 0.626,6.335 -6.97,6.215 -6.97,6.215"
+ id="path49"
+ style="fill:#000000;fill-opacity:1;stroke:#ffffff;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" /><path
+ d="m 40.02,27.894 c -6.326,0 -5.684,5.247 -5.684,5.247 l 1.286,3.326 c 0.754,2.04 -0.103,3.644 -0.103,3.644 0,0 -1.93,0.857 -2.041,1.929 -0.634,6.335 6.97,6.215 6.97,6.215"
+ id="path51"
+ style="fill:#000000;fill-opacity:1;stroke:#ffffff;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" /></g></g></g><circle
+ cx="40.588001"
+ cy="37.882999"
+ r="2.036"
+ id="circle53"
+ style="fill:#ffffff;stroke:#010101;stroke-linecap:round;stroke-linejoin:round" /><g
+ id="XMLID_2_"
+ style="fill:#000000;fill-opacity:1;stroke:#ffffff;stroke-opacity:1"><g
+ id="g56"
+ style="fill:#000000;fill-opacity:1;stroke:#ffffff;stroke-opacity:1"><polygon
+ points="41.959,33.452 39.258,33.452 39.385,8.128 41.705,8.001 "
+ id="polygon58"
+ style="fill:#000000;fill-opacity:1;stroke:#ffffff;stroke-opacity:1" /></g><g
+ id="g60"
+ style="fill:#000000;fill-opacity:1;stroke:#ffffff;stroke-opacity:1"><polygon
+ points="41.959,33.452 39.258,33.452 39.385,8.128 41.705,8.001 "
+ id="polygon62"
+ style="fill:#000000;fill-opacity:1;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" /></g></g></svg> \ No newline at end of file
diff --git a/icons/notes.svg b/icons/notes.svg
new file mode 100644
index 0000000..b020ff7
--- /dev/null
+++ b/icons/notes.svg
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.1"
+ width="55"
+ height="55"
+ viewBox="0 0 55 55"
+ id="svg2"
+ xml:space="preserve"
+ inkscape:version="0.48.4 r9939"
+ sodipodi:docname="notes.svg"><sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1366"
+ inkscape:window-height="709"
+ id="namedview8"
+ showgrid="false"
+ inkscape:zoom="4.2909091"
+ inkscape:cx="-13.983051"
+ inkscape:cy="27.5"
+ inkscape:window-x="0"
+ inkscape:window-y="27"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg2" /><metadata
+ id="metadata11"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
+ id="defs9" /><path
+ d="m 17.666,7.884 0,32.841 c -2.587,-0.614 -7.914,-0.612 -10.755,1.764 -5.688,4.76 -0.695,10.109 5.815,7.456 3.705,-1.512 4.94,-3.937 4.94,-7.597 l 0,-20.351 30.952,-3.516 0,16.974 c -4.212,-0.615 -7.915,-0.614 -10.758,1.764 -5.688,4.76 -0.695,10.109 5.815,7.454 3.705,-1.51 4.942,-3.936 4.942,-7.596 l 0,-32.784 z m 30.952,7.976 -30.952,4.029 0,-9.225 30.953,-4.102 0,9.298 z"
+ id="path5"
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:3.5;stroke-opacity:1;display:inline"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccscccccscccccccc" /></svg> \ No newline at end of file
diff --git a/icons/octaves.svg b/icons/octaves.svg
new file mode 100644
index 0000000..cd25aaa
--- /dev/null
+++ b/icons/octaves.svg
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ version="1.1"
+ width="55"
+ height="55"
+ viewBox="0 0 55 55"
+ id="svg2"
+ xml:space="preserve"><metadata
+ id="metadata11"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
+ id="defs9" /><path
+ d="m 12.517176,49.301882 c 0.647737,-0.193553 1.757707,0.299504 2.575609,-1.834902 0.483736,-1.262363 -0.507138,-3.296529 -1.828314,-3.58298 -1.326772,-0.287664 -3.023451,1.168667 -3.4360789,2.462039 -0.3980445,1.247661 0.3992769,2.836376 1.3810199,3.703138 1.236012,1.091252 3.267974,1.372577 4.857411,0.934117 1.488145,-0.410518 3.171168,-1.565407 3.456236,-3.082588 0.347427,-1.849066 -0.121069,-3.781924 -0.373648,-5.698117 -1.170046,-8.876574 -3.996508,-17.391184 -5.604705,-26.342118 -0.429978,-2.393179 -0.101009,-5.05783 1.414353,-6.9593727 0.609033,-0.7642412 1.672049,-1.5322354 2.542274,-1.0876078 1.197117,0.6116476 0.793061,2.6944445 0.434118,3.9899605 -0.71775,2.590543 -2.156321,3.616371 -3.643451,5.458196 -1.882917,2.332011 -6.0448687,5.812774 -7.3050981,8.532236 -1.4517284,3.1327 -1.2039678,5.112554 -0.074431,8.375294 0.9291933,2.684036 3.4129581,4.979255 6.0717641,5.978353 1.985445,0.74607 4.510088,0.678005 6.352,-0.373648 1.889914,-1.07906 3.431693,-3.251901 3.643059,-5.417882 0.26566,-2.722366 -0.83512,-6.151386 -3.176,-7.566353 -1.551282,-0.937687 -3.950965,-0.610927 -5.517882,0.300392 -1.470805,0.855421 -2.69944,2.307894 -3.062432,3.970196 -0.26975,1.235309 0.225483,3.080234 0.920549,4.136471 0.593428,0.901785 1.966495,2.5585 2.708941,1.774824 0.903742,-0.953929 -2.229845,-1.866187 -2.335294,-3.176 -0.115102,-1.429717 0.754155,-2.977041 1.99498,-3.69655 1.159514,-0.672358 2.813622,-0.600894 3.983373,0.05349 1.64308,0.919177 2.645372,2.68788 2.642667,4.570588 -0.0021,1.433665 -0.707849,2.846411 -1.895373,3.649647 -1.426708,0.965019 -3.33562,1.338634 -5.044235,1.120941 -1.630032,-0.20768 -3.207162,-1.10162 -4.3903528,-2.241881 C 8.7041613,36.18775 7.7616252,34.755906 7.5663529,33.235059 7.345143,31.512201 8.0313852,29.709697 8.8741176,28.190824 10.519709,25.224942 13.874282,23.546531 15.88,20.811294 18.071252,17.82304 19.49693,14.812162 19.523059,11.470118 19.545397,8.6130334 18.304968,3.9158712 16.467215,3.7033729 14.629462,3.4908745 14.167109,4.8792542 13.043921,7.1871376 11.920733,9.495021 12.094217,12.691231 12.517178,15.019765 c 1.96074,10.7945 4.873238,20.222785 5.698118,31.573177 0.0919,1.264528 -0.417686,2.435456 -1.400785,3.236078 -0.644236,0.524656 -1.136248,0.685311 -1.962039,0.593804 -0.85821,-0.0951 -2.267916,-0.260112 -2.335296,-1.120942 z"
+ id="path3757"
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-opacity:0.94117647" /><g
+ id="g3797"><path
+ d="m 28.243605,33.032751 c 3.402262,-1.341368 7.477036,-3.584483 10.460595,-6.371453 2.127362,-1.987188 4.213259,-4.341003 5.040105,-7.132223 0.459528,-1.551248 0.346071,-3.323493 -0.190193,-4.849912 -0.60101,-1.710711 -1.706573,-3.396204 -3.233275,-4.374431 -1.308623,-0.8384943 -4.184238,-0.9509628 -4.564623,-0.9509628 -0.380385,0 -3.790507,0.428269 -5.135201,1.6166378 -1.201088,1.061457 -2.229078,2.788412 -1.997022,4.37443 0.195131,1.33365 1.366488,2.673563 2.662696,3.043082 1.147521,0.327132 2.799992,-0.02866 3.423468,-1.046059 0.571838,-0.933133 0.16217,-2.420369 -0.570578,-3.233275 -0.309019,-0.342823 -0.872813,-0.327805 -1.331349,-0.380385 -0.630635,-0.07231 -1.341912,0.393955 -1.901926,0.0951 -0.163067,-0.08702 -0.291307,-0.290746 -0.285289,-0.475482 0.03263,-1.001872 0.840974,-1.975927 1.711734,-2.472504 1.545937,-0.881616 3.812341,-1.3173158 5.325393,-0.380385 1.981889,1.227249 2.607242,4.13611 2.662697,6.466549 0.06726,2.826617 -1.31119,5.617975 -2.852889,7.988091 -0.978054,1.503602 -3.518564,3.328371 -3.898949,3.708756 -0.380385,0.380385 -3.955634,2.725601 -5.800875,3.61366 -0.06746,0.291336 0.184487,0.691846 0.475481,0.760766 z"
+ id="path3759"
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:0.94117647" /><path
+ d="m 42.603147,36.170929 a 0.85586685,0.95096314 0 1 1 -1.711734,0 0.85586685,0.95096314 0 1 1 1.711734,0 z"
+ transform="matrix(0.69553117,0,0,0.62597808,18.226331,-9.4845886)"
+ id="path3763"
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:3.5;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0.94117647;stroke-dasharray:none" /><path
+ d="m 42.603147,36.170929 a 0.85586685,0.95096314 0 1 1 -1.711734,0 0.85586685,0.95096314 0 1 1 1.711734,0 z"
+ transform="matrix(0.69553117,0,0,0.62597808,18.226333,-1.7817854)"
+ id="path3763-7"
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:3.5;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0.94117647;stroke-dasharray:none" /></g><g
+ transform="translate(-24.6,3.8)"
+ id="text2993"
+ style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-opacity:0.94117647;font-family:Sans" /></svg> \ No newline at end of file
diff --git a/measure.py b/measure.py
index b8fb7ec..4b5b12f 100644
--- a/measure.py
+++ b/measure.py
@@ -286,6 +286,8 @@ class MeasureActivity(activity.Activity):
if not self._extra_tools in self._extras_toolbar_item:
self._extras_toolbar_item.add(self._extra_tools)
self._extras_toolbar_item.show()
+ self.sensor_toolbar.log_label.hide()
+ self.sensor_toolbar.trigger_label.hide()
else:
self._extras_button.hide()
if self._extra_tools in self._extras_toolbar_item:
@@ -295,6 +297,8 @@ class MeasureActivity(activity.Activity):
if self._extras_button.is_expanded():
self._extras_button.set_expanded(False)
self._extras_toolbar_item.hide()
+ self.sensor_toolbar.log_label.show()
+ self.sensor_toolbar.trigger_label.show()
self._extra_tools.show()
def on_quit(self, data=None):
@@ -432,8 +436,7 @@ class MeasureActivity(activity.Activity):
self.freq.set_icon('domain-freq')
self.freq.set_tooltip(_('Frequency Base'))
# Turn off triggering in Frequencey Base
- self.sensor_toolbar.trigger_combo.set_active(
- self.wave.TRIGGER_NONE)
+ self.sensor_toolbar.trigger_none.set_active(True)
self.wave.set_trigger(self.wave.TRIGGER_NONE)
# Turn off invert in Frequencey Base
for i in range(self.audiograb.channels):
diff --git a/sensor_toolbar.py b/sensor_toolbar.py
index 5338e38..711146e 100644
--- a/sensor_toolbar.py
+++ b/sensor_toolbar.py
@@ -26,14 +26,16 @@ from config import ICONS_DIR, CAPTURE_GAIN, MIC_BOOST, XO1, XO15, XO175, XO4
from sugar.graphics.toolbutton import ToolButton
from sugar.graphics.menuitem import MenuItem
-from sugar.graphics.combobox import ComboBox
-from sugar.graphics.toolcombobox import ToolComboBox
from sugar.graphics.radiotoolbutton import RadioToolButton
import logging
log = logging.getLogger('measure-activity')
log.setLevel(logging.DEBUG)
LOG_TIMER_VALUES = [1, 10, 300, 3000, 18000] # In 10th second intervals
+LOG_TIMER_LABELS = {1: _('1/10 second'), 10: _('1 second'),
+ 300: _('30 seconds'), 3000: _('5 minutes'),
+ 30000: _('30 minutes')}
+
def _is_xo(hw):
''' Return True if this is xo hardware '''
@@ -120,8 +122,13 @@ of XO)") + ' '
self.insert(separator, -1)
self._log_value = LOG_TIMER_VALUES[1]
+ self.log_label = gtk.Label(self._log_to_string(self._log_value))
+ toolitem = gtk.ToolItem()
+ toolitem.add(self.log_label)
+ self.insert(toolitem, -1)
+
self._log_button = ToolButton('timer-10')
- self._log_button.set_tooltip(_('Select log'))
+ self._log_button.set_tooltip(_('Select logging interval'))
self._log_button.connect('clicked', self._log_selection_cb)
self.insert(self._log_button, -1)
self._setup_log_palette()
@@ -129,13 +136,18 @@ of XO)") + ' '
# Set up Logging/Stop Logging Button
self._record = ToolButton('media-record')
self.insert(self._record, -1)
- self._record.set_tooltip(_('Start Recording'))
+ self._record.set_tooltip(_('Start logging'))
self._record.connect('clicked', self.record_control_cb)
separator = gtk.SeparatorToolItem()
separator.props.draw = True
self.insert(separator, -1)
+ toolitem = gtk.ToolItem()
+ self.trigger_label = gtk.Label(_('Trigger'))
+ toolitem.add(self.trigger_label)
+ self.insert(toolitem, -1)
+
# Set up Trigger Combo box
self.trigger_none = RadioToolButton()
self.trigger_none.set_named_icon('trigger-none')
@@ -174,6 +186,7 @@ of XO)") + ' '
def set_log_idx(self, idx):
self._log_value = LOG_TIMER_VALUES[idx]
+ self.log_label.set_text(self._log_to_string(self._log_value))
if hasattr(self, '_log_button'):
self._log_button.set_icon('timer-%d' % (self._log_value))
@@ -189,27 +202,20 @@ of XO)") + ' '
def _log_to_seconds(self, tenth_seconds):
return tenth_seconds / 10.
- def _log_to_string(self, seconds):
- tenth_seconds = seconds / 10
- if seconds == 1:
- return _('1/10 second')
+ def _log_to_string(self, tenth_seconds):
+ if tenth_seconds in LOG_TIMER_LABELS:
+ return LOG_TIMER_LABELS[tenth_seconds]
else:
- return ngettext('%d second', '%d seconds', tenth_seconds) % \
- tenth_seconds
+ return _('1 second')
def _setup_log_palette(self):
self._log_palette = self._log_button.get_palette()
- for seconds in LOG_TIMER_VALUES:
- tenth_seconds = seconds / 10
- if seconds == 1:
- text = _('1/10 second')
- else:
- text = ngettext('%d second', '%d seconds', tenth_seconds) % \
- tenth_seconds
- menu_item = MenuItem(icon_name='timer-%d' % (seconds),
- text_label=text)
- menu_item.connect('activate', self._log_selected_cb, seconds)
+ for tenth_seconds in LOG_TIMER_VALUES:
+ text = self._log_to_string(tenth_seconds)
+ menu_item = MenuItem(icon_name='timer-%d' % (tenth_seconds),
+ text_label=self._log_to_string(tenth_seconds))
+ menu_item.connect('activate', self._log_selected_cb, tenth_seconds)
self._log_palette.menu.append(menu_item)
menu_item.show()
@@ -252,7 +258,7 @@ of XO)") + ' '
if button is None:
value = self.activity.wave.TRIGGER_NONE
if self.activity.wave.get_fft_mode():
- self.trigger_combo.set_active(self.activity.wave.TRIGGER_NONE)
+ self.trigger_none.set_active(True)
else:
self.activity.wave.set_trigger(value)
@@ -400,7 +406,7 @@ of XO)") + ' '
''' Called when an analog sensor is selected '''
self.activity.wave.set_mag_params(self.gain, self.y_mag)
self.update_string_for_textbox()
- self.update_trigger_control_cb(None)
+ self.update_trigger_control_cb(None, self.activity.wave.TRIGGER_NONE)
self.activity.audiograb.start_grabbing()
return False
diff --git a/tuning_toolbar.py b/tuning_toolbar.py
index a38f396..d2616db 100644
--- a/tuning_toolbar.py
+++ b/tuning_toolbar.py
@@ -21,16 +21,15 @@ from config import XO175, INSTRUMENT_DICT
from audiograb import check_output
from sugar.graphics.toolbutton import ToolButton
-from sugar.graphics.combobox import ComboBox
-from sugar.graphics.toolcombobox import ToolComboBox
+from sugar.graphics.menuitem import MenuItem
from sugar.graphics import style
import logging
log = logging.getLogger('measure-activity')
log.setLevel(logging.DEBUG)
-NOTES = ['C', 'C♯/D♭', 'D', 'D♯/E♭', 'E', 'F', 'F♯/G♭', 'G', 'G♯/A♭', 'A',
- 'A♯/B♭', 'B']
+NOTES = ['A', 'A♯/B♭', 'B', 'C', 'C♯/D♭', 'D', 'D♯/E♭', 'E', 'F', 'F♯/G♭',
+ 'G', 'G♯/A♭']
SHARP = '♯'
FLAT = '♭'
A0 = 27.5
@@ -53,47 +52,38 @@ class TuningToolbar(gtk.Toolbar):
self._updating_note = True
self._tuning_tool = None
- # Set up Instrument Combo box
- self.instrument_combo = ComboBox()
- self.instrument = [_('None')]
- for k in INSTRUMENT_DICT.keys():
- self.instrument.append(k)
- self._instrument_changed_id = self.instrument_combo.connect(
- 'changed', self.update_instrument_control)
- for i, instrument in enumerate(self.instrument):
- self.instrument_combo.append_item(i, instrument, None)
- self.instrument_combo.set_active(0)
- if hasattr(self.instrument_combo, 'set_tooltip_text'):
- self.instrument_combo.set_tooltip_text(_('Tune an instrument.'))
- self._instrument_tool = ToolComboBox(self.instrument_combo)
- self.insert(self._instrument_tool, -1)
+ self._instrument_button = ToolButton('instruments')
+ self._instrument_button.set_tooltip(_('Tune an instrument.'))
+ self._instrument_button.connect('clicked',
+ self._button_selection_cb)
+ self.insert(self._instrument_button, -1)
+ self._setup_instrument_palette()
separator = gtk.SeparatorToolItem()
separator.props.draw = True
self.insert(separator, -1)
- self._notes_combo = ComboBox()
- n = 0
- for octave in range(9):
- for i in range(len(NOTES)):
- if octave == 0 and i < 9: # Start with A0
- continue
- self._notes_combo.append_item(
- n, note_octave(i, octave), None)
- n += 1
- self._notes_combo.set_active(48) # A4
- self._notes_changed_id = self._notes_combo.connect(
- 'changed', self.update_note)
- if hasattr(self._notes_combo, 'set_tooltip_text'):
- self._notes_combo.set_tooltip_text(_('Notes'))
- self._notes_tool = ToolComboBox(self._notes_combo)
- self.insert(self._notes_tool, -1)
+ self._note = 'A'
+ self._notes_button = ToolButton('notes')
+ self._notes_button.set_tooltip(_('Notes'))
+ self._notes_button.connect('clicked',
+ self._button_selection_cb)
+ self.insert(self._notes_button, -1)
+ self._setup_notes_palette()
+
+ self._octave = 4
+ self._octaves_button = ToolButton('octaves')
+ self._octaves_button.set_tooltip(_('Octaves'))
+ self._octaves_button.connect('clicked',
+ self._button_selection_cb)
+ self.insert(self._octaves_button, -1)
+ self._setup_octaves_palette()
# The entry is used to display a note or for direct user input
self._freq_entry = gtk.Entry()
self._freq_entry.set_text('440') # A
self._freq_entry_changed_id = self._freq_entry.connect(
- 'changed', self.update_freq_entry)
+ 'changed', self._update_freq_entry)
if hasattr(self._freq_entry, 'set_tooltip_text'):
self._freq_entry.set_tooltip_text(
_('Enter a frequency to display.'))
@@ -145,51 +135,22 @@ class TuningToolbar(gtk.Toolbar):
self.show_all()
- def update_note(self, *args):
- ''' Calculate the frequency based on note combo '''
+ def _update_note(self):
+ ''' Calculate the frequency based on note and octave '''
if not hasattr(self, '_freq_entry'): # Still setting up toolbar
return
- i = self._notes_combo.get_active()
+ i = self._octave * 12 + NOTES.index(self._note)
freq = A0 * pow(TWELTHROOT2, i)
self._updating_note = True
self._freq_entry.set_text('%0.3f' % (freq))
self.label.set_markup(SPAN % (style.COLOR_WHITE.get_html(),
- note_octave(index_to_note(i),
- index_to_octave(i))))
+ self._note + str(self._octave)))
if self._show_tuning_line:
self.activity.wave.tuning_line = freq
return
- def update_tuning_control(self, *args):
- ''' Update note '''
- if not hasattr(self, '_freq_entry'): # Still setting up toolbar?
- return
- instrument = self.instrument[self.instrument_combo.get_active()]
- if not instrument in INSTRUMENT_DICT:
- return
- if self.tuning[self._tuning_combo.get_active()] == _('All notes'):
- self._notes_combo.set_active(
- freq_index(INSTRUMENT_DICT[instrument][0]))
- self.activity.wave.instrument = instrument
- self.activity.wave.tuning_line = 0.0
- self._new_tuning_line.set_icon('tuning-tools')
- self._new_tuning_line.set_tooltip(_('Show tuning line.'))
- self._show_tuning_line = False
- else:
- freq = INSTRUMENT_DICT[instrument][
- self._tuning_combo.get_active() - 1] # All notes is 0
- self._notes_combo.set_active(
- freq_index(INSTRUMENT_DICT[instrument][
- self._tuning_combo.get_active() - 1]))
- self.activity.wave.instrument = None
- self.activity.wave.tuning_line = freq
- self._new_tuning_line.set_icon('tuning-tools-off')
- self._new_tuning_line.set_tooltip(_('Hide tuning line.'))
- self._show_tuning_line = True
- self._updating_note = False
-
- def update_freq_entry(self, *args):
- # Calcualte a note from a frequency
+ def _update_freq_entry(self, widget):
+ # Calculate a note from a frequency
if not self._updating_note: # Only if user types in a freq.
try:
freq = float(self._freq_entry.get_text())
@@ -203,41 +164,139 @@ class TuningToolbar(gtk.Toolbar):
self.label.set_markup(freq_note(freq, flatsharp=True))
except ValueError:
return
+
self._updating_note = False
- def update_instrument_control(self, *args):
+ def _button_selection_cb(self, widget):
+ palette = widget.get_palette()
+ if palette:
+ if not palette.is_up():
+ palette.popup(immediate=True, state=palette.SECONDARY)
+ else:
+ palette.popdown(immediate=True)
+ return
+
+ def _setup_notes_palette(self):
+ self._notes_palette = self._notes_button.get_palette()
+
+ for note in NOTES:
+ menu_item = MenuItem(icon_name='',
+ text_label=note)
+ menu_item.connect('activate', self._note_selected_cb, note)
+ self._notes_palette.menu.append(menu_item)
+ menu_item.show()
+
+ def _note_selected_cb(self, widget, note):
+ self._note = note
+ self._update_note()
+
+ def _setup_octaves_palette(self):
+ self._octaves_palette = self._octaves_button.get_palette()
+
+ for octave in range(9):
+ menu_item = MenuItem(icon_name='',
+ text_label=str(octave))
+ menu_item.connect('activate', self._octave_selected_cb, octave)
+ self._octaves_palette.menu.append(menu_item)
+ menu_item.show()
+
+ def _octave_selected_cb(self, widget, octave):
+ self._octave = octave
+ self._update_note()
+
+ def _setup_instrument_palette(self):
+ self.instrument_palette = self._instrument_button.get_palette()
+
+ self.instrument = []
+ for k in INSTRUMENT_DICT.keys():
+ self.instrument.append(k)
+ menu_item = MenuItem(icon_name='',
+ text_label=k)
+ menu_item.connect('activate', self.instrument_selected_cb, k)
+ self.instrument_palette.menu.append(menu_item)
+ menu_item.show()
+
+ def instrument_selected_cb(self, button, instrument):
''' Callback for instrument control '''
- instrument = self.instrument[self.instrument_combo.get_active()]
+ logging.debug(instrument)
if self._tuning_tool is not None:
self.remove(self._tuning_tool)
+
if instrument == _('None'):
self.activity.wave.instrument = None
- if hasattr(self, '_notes_tool'):
- self.insert(self._notes_tool, 2)
+
+ # Remove any previous tuning button
+ if hasattr(self, '_tuning_button'):
+ self._tuning_button.destroy()
+
+ # Restore the notes, octaves buttons
+ if hasattr(self, '_notes_button'):
+ self.insert(self._notes_button, 2)
+ self.insert(self._octaves_button, 3)
return
- self.remove(self._notes_tool)
+
+ self.remove(self._notes_button)
+ self.remove(self._octaves_button)
+
self.activity.wave.instrument = instrument
+
# If we are not already in freq. base, switch.
if not self.activity.wave.get_fft_mode():
self.activity.timefreq_control()
- # Add a Tuning Combo box for this instrument
- self._tuning_combo = ComboBox()
- self.tuning = [_('All notes')]
- for f in INSTRUMENT_DICT[instrument]:
+
+ # Add a Tuning palette for this instrument
+ self._tuning_button = ToolButton('notes')
+ self._tuning_button.set_tooltip(instrument)
+ self._tuning_button.connect('clicked', self._button_selection_cb)
+ self.insert(self._tuning_button, 1)
+ self._setup_tuning_palette(instrument)
+
+ def _setup_tuning_palette(self, instrument):
+ self._tuning_palette = self._tuning_button.get_palette()
+
+ self.tuning = []
+ self.tuning.append(_('All notes'))
+ menu_item = MenuItem(icon_name='', text_label=_('All notes'))
+ menu_item.connect('activate', self._tuning_selected_cb,
+ instrument, -1)
+ self._tuning_palette.menu.append(menu_item)
+ menu_item.show()
+
+ for i, f in enumerate(INSTRUMENT_DICT[instrument]):
self.tuning.append(freq_note(f))
- self._tuning_changed_id = self._tuning_combo.connect(
- 'changed', self.update_tuning_control)
- for i, s in enumerate(self.tuning):
- self._tuning_combo.append_item(i, s, None)
- self._tuning_combo.set_active(0)
- if hasattr(self._tuning_combo, 'set_tooltip_text'):
- self._tuning_combo.set_tooltip_text(instrument)
- self._tuning_tool = ToolComboBox(self._tuning_combo)
- self.insert(self._tuning_tool, 1)
- self._tuning_combo.show()
- self._tuning_tool.show()
+ menu_item = MenuItem(icon_name='',
+ text_label=freq_note(f))
+ menu_item.connect('activate', self._tuning_selected_cb,
+ instrument, i)
+ self._tuning_palette.menu.append(menu_item)
+ menu_item.show()
+
self.show_all()
+ def _tuning_selected_cb(self, widget, instrument, fidx):
+ ''' Update note '''
+ if not hasattr(self, '_freq_entry'): # Still setting up toolbar?
+ return
+
+ if not instrument in INSTRUMENT_DICT:
+ return
+
+ if fidx == -1: # All notes
+ self.activity.wave.instrument = instrument
+ self.activity.wave.tuning_line = 0.0
+ self._new_tuning_line.set_icon('tuning-tools')
+ self._new_tuning_line.set_tooltip(_('Show tuning line.'))
+ self._show_tuning_line = False
+ else:
+ freq = INSTRUMENT_DICT[instrument][fidx]
+ self.activity.wave.instrument = None
+ self.activity.wave.tuning_line = freq
+ self._new_tuning_line.set_icon('tuning-tools-off')
+ self._new_tuning_line.set_tooltip(_('Hide tuning line.'))
+ self._show_tuning_line = True
+
+ self._updating_note = False
+
def harmonic_cb(self, *args):
''' Callback for harmonics control '''
self.activity.wave.harmonics = not self.activity.wave.harmonics
@@ -330,27 +389,65 @@ class InstrumentToolbar(gtk.Toolbar):
self.insert(toolitem, -1)
toolitem.show()
- self._notes_combo = ComboBox()
- n = 0
- for octave in range(9):
- for i in range(len(NOTES)):
- if octave == 0 and i < 9: # Start with A0
- continue
- self._notes_combo.append_item(
- n, note_octave(i, octave), None)
- n += 1
- self._notes_combo.set_active(48) # A4
- if hasattr(self._notes_combo, 'set_tooltip_text'):
- self._notes_combo.set_tooltip_text(_('Notes'))
- self._notes_tool = ToolComboBox(self._notes_combo)
- self.insert(self._notes_tool, -1)
- self._notes_tool.show()
+ self._note = 'A'
+ self._notes_button = ToolButton('notes')
+ self._notes_button.set_tooltip(_('Notes'))
+ self._notes_button.connect('clicked',
+ self._button_selection_cb)
+ self.insert(self._notes_button, -1)
+ self._setup_notes_palette()
+ self._notes_button.show()
+
+ self._octave = 4
+ self._octaves_button = ToolButton('octaves')
+ self._octaves_button.set_tooltip(_('Octaves'))
+ self._octaves_button.connect('clicked',
+ self._button_selection_cb)
+ self.insert(self._octaves_button, -1)
+ self._setup_octaves_palette()
+ self._octaves_button.show()
self._new_note = ToolButton('list-add')
self._new_note.show()
self.insert(self._new_note, -1)
self._new_note.set_tooltip(_('Add a new note.'))
self._new_note.connect('clicked', self.new_note_cb)
+ self._new_note.show()
+
+ def _button_selection_cb(self, widget):
+ palette = widget.get_palette()
+ if palette:
+ if not palette.is_up():
+ palette.popup(immediate=True, state=palette.SECONDARY)
+ else:
+ palette.popdown(immediate=True)
+ return
+
+ def _setup_notes_palette(self):
+ self._notes_palette = self._notes_button.get_palette()
+
+ for note in NOTES:
+ menu_item = MenuItem(icon_name='',
+ text_label=note)
+ menu_item.connect('activate', self._note_selected_cb, note)
+ self._notes_palette.menu.append(menu_item)
+ menu_item.show()
+
+ def _note_selected_cb(self, widget, note):
+ self._note = note
+
+ def _setup_octaves_palette(self):
+ self._octaves_palette = self._octaves_button.get_palette()
+
+ for octave in range(9):
+ menu_item = MenuItem(icon_name='',
+ text_label=str(octave))
+ menu_item.connect('activate', self._octave_selected_cb, octave)
+ self._octaves_palette.menu.append(menu_item)
+ menu_item.show()
+
+ def _octave_selected_cb(self, widget, octave):
+ self._octave = octave
def update_name_entry(self, *args):
''' Add name to INSTRUMENT_DICT and combo box '''
@@ -364,21 +461,29 @@ class InstrumentToolbar(gtk.Toolbar):
INSTRUMENT_DICT[name] = []
self.activity.tuning_toolbar.instrument.append(name)
i = len(self.activity.tuning_toolbar.instrument)
- self.activity.tuning_toolbar.instrument_combo.append_item(
- i, name, None)
+ menu_item = MenuItem(icon_name='',
+ text_label=name)
+ menu_item.connect(
+ 'activate',
+ self.activity.tuning_toolbar.instrument_selected_cb,
+ name)
+ self.activity.tuning_toolbar.instrument_palette.menu.append(
+ menu_item)
+ menu_item.show()
self.new_instruments.append(name)
- i = self._notes_combo.get_active()
- freq = A0 * pow(TWELTHROOT2, i)
+
+ freq = A0 * pow(TWELTHROOT2,
+ self._octave * 12 + NOTES.index(self._note))
if freq not in INSTRUMENT_DICT[name]:
INSTRUMENT_DICT[name].append(freq)
def note_octave(note, octave):
- if '/' in NOTES[note]:
- flat, sharp = NOTES[note].split('/')
+ if '/' in note:
+ flat, sharp = note.split('/')
return '%s%d/%s%d' % (flat, octave, sharp, octave)
else:
- return '%s%d' % (NOTES[note], octave)
+ return '%s%d' % (note, octave)
def freq_note(freq, flatsharp=False):
@@ -386,7 +491,7 @@ def freq_note(freq, flatsharp=False):
for i in range(88):
f = A0 * pow(TWELTHROOT2, i)
if freq < f * 1.03 and freq > f * 0.97:
- label = NOTES[index_to_note(i)]
+ label = NOTES[i % 12] + str(int(i / 12))
if freq < f * 0.98:
label = '%s %s %s' % (FLAT, label, FLAT)
return SPAN % (COLOR_RED.get_html(), label)
@@ -405,7 +510,7 @@ def freq_note(freq, flatsharp=False):
for i in range(88):
f = A0 * pow(TWELTHROOT2, i)
if freq < f * 1.03 and freq > f * 0.97: # Found a match
- return note_octave(index_to_note(i), index_to_octave(i))
+ return note_octave(NOTES[i % 12], int(i / 12))
return '?'