Pastebin launched a little side project called VERYVIRAL.com, check it out ;-) Want more features on Pastebin? Sign Up, it's FREE!
Guest

chords.py_1.2

By: rhowaldt on Mar 15th, 2012  |  syntax: None  |  size: 21.16 KB  |  views: 202  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
This paste has a previous version, view the difference. Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. #!/usr/bin/python
  2. import curses
  3. import sys
  4. sys.stdout.write("\x1b]2;Chords!\x07") # set the terminal window title
  5.  
  6. myscreen = curses.initscr()
  7. #myscreen.box()
  8. myscreen.keypad(1)
  9. myscreen.refresh()
  10.  
  11. maxheight,maxwidth = myscreen.getmaxyx()
  12. #myscreen.addstr(1,1,str(maxwidth)) # debug
  13. #myscreen.addstr(2,1,str(maxheight)) # debug
  14.  
  15. curses.start_color()
  16. curses.use_default_colors()
  17. curses.noecho()
  18. curses.cbreak()
  19. curses.curs_set(0)
  20. curses.init_pair(1, curses.COLOR_BLACK, curses.COLOR_WHITE)
  21. curses.init_pair(2, curses.COLOR_WHITE, curses.COLOR_BLACK)
  22.  
  23. # DEFINE DICTIONARIES
  24. pianokeys_1 = { # pianokeys_layout = 1
  25. 1: 'C', 2: 'C#', 3: 'D', 4: 'D#', 5: 'E', 6: 'F', 7: 'F#', 8: 'G', 9: 'G#',
  26. 10: 'A', 11: 'A#', 12: 'B'}
  27.  
  28. pianokeys_2 = { # pianokeys_layout = 2
  29. 1: 'C', 2: 'Db', 3: 'D', 4: 'Eb', 5: 'E', 6: 'F', 7: 'Gb', 8: 'G', 9: 'Ab',
  30. 10: 'A', 11: 'Bb', 12: 'B'}
  31.  
  32. pckeys = {
  33. 1: 'z', 2: 's', 3: 'x', 4: 'd', 5: 'c', 6: 'v', 7: 'g', 8: 'b', 9: 'h',
  34. 10: 'n', 11: 'j', 12: 'm'}
  35.  
  36. subnotes = { # display this, this is purely for the display of the chord-name
  37. 1: 'M(ajor)', 2: 'm(inor)', 3: 'M6', 4: 'm6', 5: '7',
  38. 6: 'M7', 7: 'm7', 8: 'mM7', 9: '9', 10: 'M9', 11: 'm9',
  39. 12: 'mM9', 13: 'M11', 14: 'm11', 15: 'mM11',
  40. 16: 'M13', 17: 'm13', 18: 'mM13',
  41. 19: 'M-add9', 20: 'm-add9', 21: 'M6-add9', 22: 'm6-add9',
  42. 23: 'dom7', 24: 'dom9', 25: 'dom11', 26: 'dom13',
  43. 27: 'sus2', 28: 'sus4', 29: '6-sus4', 30: '7-sus4', 31: 'm7-sus4',
  44. 32: '9-sus4', 33: 'm9-sus4', 34: '7b5', 35: 'm7b5', 36: '7#5', 37: 'm7#5',
  45. 38: '7b9', 39: 'm7b9', 40: '7#9', 41: '7#5b9', 42: '9#11', 43: '9b13',
  46. 44: 'dim', 45: 'dim7', 46: 'add2', 47: 'add4', 48: '7-add4',
  47. 49: '5', 50: 'aug'}
  48.  
  49. chord_formulas = { # use these, these are for calculating the chords
  50. 1: [1,3,5], 2: [1,'b3',5], 3: [1,3,5,6], 4: [1,'b3',5,6], 5: [1,3,5,'b7'],
  51. 6: [1,3,5,7], 7: [1,'b3',5,'b7'], 8: [1,'b3',5,7], 9: [1,3,5,'b7',9], 10: [1,3,5,7,9], 11: [1,'b3',5,'b7',9],
  52. 12: [1,'b3',5,7,9], 13: [1,3,5,7,9,11], 14: [1,'b3',5,'b7',9,11], 15: [1,'b3',5,7,9,11],
  53. 16: [1,5,7,9,11,13], 17: [1,'b3',5,'b7',9,11,13], 18: [1,'b3',5,7,9,11,13],
  54. 19: [1,3,5,9], 20: [1,'b3',5,9], 21: [1,3,5,6,9], 22: [1,'b3',5,6,9],
  55. 23: [1,3,5,'b7'], 24: [1,3,5,'b7',9], 25: [1,3,5,'b7',9,11], 26: [1,3,5,'b7',9,11,13],
  56. 27: [1,2,5], 28: [1,4,5], 29: [1,4,5,6], 30: [1,4,5,'b7'], 31: [1,4,5,7],
  57. 32: [1,4,5,'b7',9], 33: [1,4,5,7,9], 34: [1,3,'b5',7], 35: [1,'b3','b5','b7'],
  58. 36: [1,3,'#5','b7'], 37: [1,'b3','#5','b7'], 38: [1,3,5,'b7','b9'],
  59. 39: [1,'b3',5,'b7','b9'], 40: [1,3,5,'b7','#9'], 41: [1,3,'#5','b7','b9'],
  60. 42: [1,3,5,'b7',9,'#11'], 43: [1,3,5,'b7',9,'b13'], 44: [1,'b3','b5'],
  61. 45: [1,'b3','b5',6], 46: [1,2,3,5], 47: [1,3,4,5], 48: [1,3,4,5,'b7'],
  62. 49: [1,5], 50: [1,3,'#5']}
  63.  
  64. # SET DEFAULTS
  65. current_window = 1 # default to notes_section
  66. ns_cursor_vpos = 1 # notes_section cursor vertical position
  67. ns_cursor_hpos = 1 # notes_section cursor horizontal position
  68. ss_cursor_vpos = 1 # subnotes_section cursor vertical position
  69. ss_cursor_hpos = 1 # subnotes_section cursor horizontal position
  70. pianokeys = pianokeys_1 # default to pianokeys layout 1
  71. current_note = 1 # default to first note
  72. current_subnote = 1 # default to first subnote
  73. major_minor = 1 # default to major scale
  74. bkeys_active = []
  75. wkeys_active = []
  76.  
  77. # THE PIANO:
  78. piano_show_what = 0 # default to showing no pianokeys/pckeys
  79. piano_pikeys_layout = 0 # default to note-type A#
  80. piano_width = 46
  81. piano_hpos = (maxwidth - 46) / 2
  82. piano = curses.newwin(7,46,1,piano_hpos)
  83. piano.box()
  84. piano.refresh()
  85.  
  86. def piano_draw_whitekeys(show_what,wkeys_a):
  87.    w_hpos = 0
  88.    wkey_hpos = {1: 2, 2: 6, 3: 6, 4: 6, 5: 6, 6: 6, 7: 6}
  89.    wkeys = {1: 'w1_key', 2: 'w2_key', 3: 'w3_key', 4: 'w4_key', 5: 'w5_key', 6: 'w6_key', 7: 'w7_key'}
  90.    wfields = {1: 'w1_field', 2: 'w2_field', 3: 'w3_field', 4: 'w4_field', 5: 'w5_field', 6: 'w6_field', 7: 'w7_field'}
  91.    wpckeys = {1: 'z', 2: 'x', 3: 'c', 4: 'v', 5: 'b', 6: 'n', 7: 'm'}
  92.    wpikeys = {1: 'C', 2: 'D', 3: 'E', 4: 'F', 5: 'G', 6: 'A', 7: 'B'}
  93.    wpikeys_translate = {1: 1, 3: 2, 5: 3, 6: 4, 8: 5, 10: 6, 12: 7} # translation for printed keyboard to actual key-positions in dict
  94.    for w in range(1, 8):
  95.       w_hpos = w_hpos + wkey_hpos[w]
  96.       wfields[w] = piano.derwin(6,6,0,w_hpos)
  97.       wfields[w].box()
  98.       wfields[w].refresh()
  99.       wkeys[w] = wfields[w].derwin(4,4,1,1)
  100.       wkeys[w].bkgd(curses.color_pair(1))
  101.      
  102.       if show_what == 0:
  103.          wkeys[w].addstr(1,1,"  ")
  104.       elif show_what == 1:
  105.          wkeys[w].addstr(1,1,wpikeys[w])
  106.       elif show_what == 2:
  107.          wkeys[w].addstr(1,1,wpckeys[w])
  108.  
  109.       wkeys[w].refresh()
  110.      
  111.    for x in wkeys_a:
  112.       wkey_activate = wpikeys_translate[x]
  113.       wfields[wkey_activate].addstr(5,2,'XX',curses.A_BOLD)
  114.       wfields[wkey_activate].refresh()
  115.  
  116. def piano_draw_blackkeys(show_what,show_pikeys_layout,bkeys_a):
  117.    b_hpos = 0
  118.    bkey_hpos = {1: 6, 2: 6, 3: 12, 4: 6, 5: 6}
  119.    bkeys = {1: 'b1_key', 2: 'b2_key', 3: 'b3_key', 4: 'b4_key', 5: 'b5_key'}
  120.    bfields = {1: 'b1_field', 2: 'b2_field', 3: 'b3_field', 4: 'b4_field', 5: 'b5_field'}
  121.    bpckeys = {1: 's', 2: 'd', 3: 'g', 4: 'h', 5: 'j'}
  122.    bpikeys_1 = {1: 'C#', 2: 'D#', 3: 'F#', 4: 'G#', 5: 'A#'}
  123.    bpikeys_2 = {1: 'Db', 2: 'Eb', 3: 'Gb', 4: 'Ab', 5: 'Bb'}
  124.    bpikeys_translate = {2: 1, 4: 2, 7: 3, 9: 4, 11: 5}
  125.    for b in range(1, 6):
  126.       b_hpos = b_hpos + bkey_hpos[b]
  127.       bfields[b] = piano.derwin(4,4,0,b_hpos)
  128.       bfields[b].box()
  129.       bfields[b].refresh()
  130.       bkeys[b] = bfields[b].derwin(3,3,1,1)
  131.       bkeys[b].bkgd(curses.color_pair(2))
  132.       bkeys[b].addstr(1,0,"  ")
  133.  
  134.       if show_pikeys_layout == 1:
  135.          bpikeys = bpikeys_2
  136.       elif show_pikeys_layout == 0:
  137.          bpikeys = bpikeys_1
  138.  
  139.       if show_what == 0:
  140.          bkeys[b].addstr(0,0,"  ")
  141.       elif show_what == 1:
  142.          bkeys[b].addstr(0,0,bpikeys[b])
  143.       elif show_what == 2:
  144.          bkeys[b].addstr(0,0,bpckeys[b] + ' ')
  145.  
  146.       bkeys[b].refresh()
  147.  
  148.    for x in bkeys_a:
  149.       bkey_activate = bpikeys_translate[x]
  150.       bfields[bkey_activate].addstr(3,1,'XX',curses.A_BOLD)
  151.       bfields[bkey_activate].refresh()
  152.  
  153. def draw_piano(the_id,key,bkeys_a,wkeys_a):
  154.    piano.clear()
  155.    global piano_pikeys_layout
  156.    global piano_show_what
  157.    if the_id == 2: #F2-switch for pianokeys layout
  158.       if key == 0:
  159.          piano_pikeys_layout = 1
  160.          send_return = 1
  161.       elif key == 1:
  162.          piano_pikeys_layout = 0
  163.          send_return = 0
  164.    if the_id == 3: #F3-switch for display pckeys/pianokeys
  165.       if key == 0:
  166.          piano_show_what = 1
  167.          send_return = 1
  168.       if key == 1:
  169.          piano_show_what = 2
  170.          send_return = 2
  171.       elif key == 2:
  172.          piano_show_what = 0
  173.          send_return = 0
  174.    if the_id == 4: #F4-switch for display pianokeys on/off
  175.       if key == 0:
  176.          piano_show_pikeys = 1
  177.          send_return = 1
  178.       elif key == 1:
  179.          piano_show_pikeys = 0
  180.          send_return = 0
  181.    if the_id == 0: # default
  182.       send_return = 0
  183.    
  184.    piano_draw_whitekeys(piano_show_what,wkeys_a) # draw white keys
  185.    piano_draw_blackkeys(piano_show_what,piano_pikeys_layout,bkeys_a) # draw black keys
  186.    return send_return # send changed value
  187.  
  188. draw_piano(0,0,bkeys_active,wkeys_active) # initialize the piano with values of 0
  189. # END OF THE PIANO
  190.  
  191. # NOTES SECTION
  192. def print_notes():
  193.    notes = {}
  194.    x = 1
  195.    while (x <= 12):
  196.       notes[x] = pianokeys[x]
  197.       x = x + 1
  198.    
  199.    notes_section.clear()
  200.    
  201.    note_hpos = 1
  202.    for i in notes:
  203.       notes_section.addstr(1,note_hpos,notes[i])
  204.       note_hpos = note_hpos + len(notes[i]) + 2
  205.    
  206.    notes_section.refresh()
  207.  
  208. notes_section_hpos = (maxwidth - 46) / 2 + 2
  209. notes_section = myscreen.derwin(3,46,8,notes_section_hpos)
  210. print_notes()
  211. myscreen.addstr(9,(notes_section_hpos - 9),'[Notes]',curses.A_BOLD)
  212. notes_section.chgat(1,1,2,curses.A_REVERSE)
  213. notes_section.refresh()
  214. # END OF NOTES SECTION
  215.  
  216. # SUBNOTES SECTION
  217. def print_subnotes():
  218.    column_width = 15
  219.    subnote_hpos = 1
  220.    subnote_vpos = 1
  221.    sn = 1
  222.    while (sn <= 50):
  223.       sn_len = len(subnotes[sn])
  224.       if subnote_vpos == (11): # if too high,
  225.          subnote_hpos = subnote_hpos + column_width  # jump to the right
  226.          subnote_vpos = 1 # and start over at the top
  227.       subnotes_section.addstr(subnote_vpos,subnote_hpos,subnotes[sn])
  228.       subnote_vpos = subnote_vpos + 1
  229.       sn = sn + 1
  230.  
  231.    subnotes_section.box()
  232.    subnotes_section.addstr(0,5,'[Subnotes]')
  233.  
  234. # determine horizontal position of the subnotes_section
  235. if maxwidth <= 75:
  236.    subnotes_section_hpos = 3
  237. elif maxwidth > 75:
  238.    subnotes_section_hpos = (maxwidth - 75) / 2
  239.  
  240. subnotes_section = myscreen.derwin(12,75,11,subnotes_section_hpos)
  241. # END OF SUBNOTES SECTION
  242.  
  243. # SCALE SECTION
  244. def build_scale(root,m):
  245.    scale = {1: pianokeys[root]}
  246.    index = root
  247.    scale_formula = [2,2,1,2,2,2,1,2,2,1,2,2,2] # Major scale
  248.    if m == 1: # Major scale
  249.       mjn = 'Major'
  250.       scale_formula = [2,2,1,2,2,2,1,2,2,1,2,2,2]
  251.    elif m == 2: # Natural Minor scale
  252.       mjn = 'Natural Minor'
  253.       scale_formula = [2,1,2,2,1,2,2,2,1,2,2,1,2]
  254.    elif m == 3: # Harmonic Minor scale
  255.       mjn = 'Harmonic Minor'
  256.       scale_formula = [2,1,2,2,1,3,1,2,1,2,2,1,3]
  257.    elif m == 4: # Melodic Minor scale
  258.       mjn = 'Melodic Minor'
  259.       scale_formula = [2,1,2,2,2,2,1,2,1,2,2,2,2]
  260.    
  261.    scaletext = mjn + ' scale of ' + scale[1] + ': '
  262.    
  263.    num = 2
  264.    for i in scale_formula:
  265.       if (index + i) <= len(pianokeys):
  266.          index = index + i
  267.       else:
  268.          index = (index + i) - len(pianokeys)
  269.       scale[num] = pianokeys[index] # add to dictionary
  270.       num = num + 1
  271.  
  272.    scale_section.clear() # erase the content of the scale section
  273.    scale_hpos = len(scaletext) + 1 # start printing the scale
  274.    count = 0
  275.    for x in scale:
  276.       if count < 7:
  277.          scale_section.addstr(1,scale_hpos,scale[x])
  278.          scale_hpos = scale_hpos + len(scale[x]) + 1
  279.          count = count + 1
  280.  
  281.    scale_section.addstr(1,1,scaletext)
  282.    #scale_section.box()
  283.    scale_section.refresh()
  284.  
  285. scale_section = myscreen.derwin(3,75,22,subnotes_section_hpos)
  286.  
  287. def build_major_scale(root):
  288.    scale = {1: pianokeys[root]}
  289.    key_reference = {1: root} # keeps a reference of the relation of scale-position to keyboard-position
  290.    index = root
  291.    scale_formula = [2,2,1,2,2,2,1,2,2,1,2,2,2] # Major scale
  292.  
  293.    num = 2
  294.    for i in scale_formula:
  295.       if (index + i) <= len(pianokeys):
  296.          index = index + i
  297.       else:
  298.          index = (index + i) - len(pianokeys)
  299.       scale[num] = pianokeys[index] # add to dictionary
  300.       key_reference[num] = index
  301.       num = num + 1    
  302.  
  303.    return scale,key_reference
  304.  
  305. build_scale(current_note,major_minor)
  306. # END OF SCALE SECTION
  307.  
  308. # CHORD SECTION
  309. def build_chord(root,chordtype):
  310.    chord = []
  311.    pckeys_chord = []
  312.    chord_formula = chord_formulas[chordtype]
  313.    scale,key_reference = build_major_scale(root)
  314.    global bkeys_active
  315.    bkeys_active = []
  316.    global wkeys_active
  317.    wkeys_active = []
  318.  
  319.    for z in chord_formula:
  320.       if isinstance(z, int) == True: # if the formula holds an integer, fine
  321.          chord.append(scale[z])
  322.          pckeys_chord.append(pckeys[key_reference[z]])
  323.          if len(scale[z]) == 1:
  324.             wkeys_active.append(key_reference[z])
  325.          else:
  326.             bkeys_active.append(key_reference[z])
  327.       elif z[0] == 'b': # if the formula holds a 'b'-note, get 1 pianokey below that note in the scale
  328.          key = int(z[1])
  329.          if key_reference[key] > 1:
  330.             note = str(pianokeys[key_reference[key] - 1])
  331.             pckey = str(pckeys[key_reference[key] - 1])
  332.             if len(note) == 1:
  333.                wkeys_active.append(key_reference[key] - 1)
  334.             else:
  335.                bkeys_active.append(key_reference[key] - 1)
  336.          elif key_reference[key] == 1: # 1-1=12 (go back around)
  337.             note = str(pianokeys[12])
  338.             pckey = str(pckeys[12])
  339.             wkeys_active.append(12) # in this case it is always a B (so white key)
  340.  
  341.          chord.append(note)
  342.          pckeys_chord.append(pckey)
  343.  
  344.       elif z[0] == '#': # if the formula has a '#'-note, get 1 pianokey above that note in the scale
  345.          key = int(z[1])
  346.          if key_reference[key] < 12:
  347.             note = str(pianokeys[key_reference[key] + 1])
  348.             pckey = str(pckeys[key_reference[key] + 1])
  349.             if len(note) == 1:
  350.                wkeys_active.append(key_reference[key] + 1)
  351.             else:
  352.                bkeys_active.append(key_reference[key] + 1)            
  353.          elif key_reference[key] == 12: # 12+1=1 (go back around)
  354.             note = str(pianokeys[1])
  355.             pckey = str(pckeys[1])
  356.             wkeys_active.append(1) # always a C (so white key)
  357.  
  358.          chord.append(note)
  359.          pckeys_chord.append(pckey)
  360.  
  361.    chord_section.clear()
  362.    
  363.    chord_hpos = 2
  364.    pckey_hpos = 2
  365.    count = 0
  366.    for y in chord:
  367.       chord_space = (len(pianokeys[root]) + len(subnotes[chordtype]) + 1)
  368.       chord_section.addstr(1,1,pianokeys[root] + ' ' + subnotes[chordtype] + ': ')
  369.       chord_section.addstr(1,(1 + chord_space + chord_hpos),y)
  370.       chord_hpos = chord_hpos + len(y) + 1
  371.       if piano_show_what == 2:
  372.          key_space = chord_space - 3
  373.          chord_section.addstr(2,key_space,'keys: ')
  374.          chord_section.addstr(2,(key_space + 4 + pckey_hpos),pckeys_chord[count])
  375.          pckey_hpos = pckey_hpos + len(y) + 1
  376.          count = count + 1
  377.  
  378.    #chord_section.box()
  379.    chord_section.refresh()
  380.    print_subnotes()
  381.    draw_piano(0,0,bkeys_active,wkeys_active)
  382.  
  383. chord_section = myscreen.derwin(4,75,24,subnotes_section_hpos)
  384. build_chord(current_note,current_subnote)
  385. print_subnotes()
  386. subnotes_section.chgat(1,1,13,curses.A_REVERSE)
  387. subnotes_section.refresh()
  388. # END OF CHORD SECTION
  389.  
  390. # NAVIGATION
  391. def tab(win,vpos,hpos): # function for tabbing between notes and subnotes sections
  392.    if win == 1: # current window = notes_section
  393.       subnotes_section.chgat(vpos,hpos,13,curses.A_REVERSE)
  394.       subnotes_section.addstr(0,5,'[Subnotes]',curses.A_BOLD) # bold title
  395.       myscreen.addstr(9,(notes_section_hpos - 9),'[Notes]',curses.A_NORMAL) # unbold title
  396.       notes_section.refresh()
  397.       subnotes_section.refresh()
  398.       return 2
  399.    elif win == 2: # current window = subnotes_section
  400.       notes_section.chgat(vpos,hpos,2,curses.A_REVERSE)
  401.       subnotes_section.addstr(0,5,'[Subnotes]',curses.A_NORMAL) # unbold title
  402.       myscreen.addstr(9,(notes_section_hpos - 9),'[Notes]',curses.A_BOLD) # bold title
  403.       notes_section.refresh()
  404.       subnotes_section.refresh()
  405.       return 1
  406.  
  407. def navigate_notes_section(vpos,hpos,note,key):
  408.    if key == 'up' or key == 'down':
  409.       () # can't go up or down from the notes section
  410.    elif key == 'right':
  411.       if note < 12:
  412.          hpos = hpos + 2 + len(pianokeys[note])
  413.          note = note + 1
  414.       else:
  415.          note = 1
  416.          hpos = 1
  417.    elif key == 'left':
  418.       if note > 1:
  419.          note = note - 1
  420.          hpos = hpos - 2 - len(pianokeys[note])
  421.       else:
  422.          note = 12
  423.          hpos = 39
  424.  
  425.    notes_section.clrtoeol() # erase the content, then redraw it
  426.    print_notes()
  427.    notes_section.chgat(vpos,hpos,2,curses.A_REVERSE)
  428.    notes_section.refresh()
  429.    return vpos,hpos,note
  430.  
  431. def navigate_subnotes_section(vpos,hpos,subnote,key): # function for moving between values
  432.    attr = curses.A_BOLD
  433.    if key == 'up':
  434.       if vpos > 1: # if we can still go up
  435.          vpos = vpos - 1 # go up
  436.          subnote = subnote - 1 # go one subnote back
  437.       else: # if we cannot go up
  438.          vpos = 10 # go to column bottom...
  439.          if hpos > 15: # check to see if we're in the 1st column
  440.             hpos = hpos - 15 # move a column back
  441.             subnote = subnote - 1 # move a subnote back
  442.          else: # if we're in the first column
  443.             hpos = 61 # jump to last column
  444.             subnote = 50 # jump to last subnote
  445.    elif key == 'down':
  446.       if vpos < 10: # if we can still go down
  447.          vpos = vpos + 1 # go down
  448.          subnote = subnote + 1 # go one subnote forward
  449.       else: # if we cannot go down
  450.          vpos = 1 # go to column top
  451.          if hpos < 61: # if we're note in the last column
  452.             hpos = hpos + 15 # move a column forward
  453.             subnote = subnote + 1 # move a subnote forward
  454.          else: # if we're in the last column
  455.             hpos = 1 # jump to first column
  456.             subnote = 1 # jump to first subnote
  457.    elif key == 'left':
  458.       if hpos > 15: # if we're not in the first column
  459.          hpos = hpos - 15 # move a column back
  460.          subnote = subnote - 10
  461.       else: # if we're in the first column
  462.          hpos = 61 # jump to last column
  463.          subnote = subnote + 40 # jump to last subnote in last column
  464.    elif key == 'right':
  465.       if hpos < 61: # if we're not in the last column
  466.          hpos = hpos + 15 # move a column to the right
  467.          subnote = subnote + 10
  468.       else:
  469.          hpos = 1 # jump to first column
  470.          subnote = subnote - 40 # jump to first subnote        
  471.    elif key == 'refresh':
  472.       if current_window == 1:
  473.          attr = curses.A_NORMAL
  474.       else:
  475.          attr = curses.A_BOLD
  476.  
  477.    subnotes_section.clrtobot() # erase the content, then redraw it
  478.    print_subnotes()
  479.    subnotes_section.addstr(0,5,'[Subnotes]',attr)
  480.    subnotes_section.chgat(vpos,hpos,13,curses.A_REVERSE)
  481.    subnotes_section.refresh()
  482.    return vpos,hpos,subnote
  483. # END OF NAVIGATION
  484.  
  485. # CAPTURE KEYPRESSES
  486. while True:
  487.    key = myscreen.getch()
  488.    if key == ord('q'): break # 'q' = quit
  489.    elif key == ord('\t'): # TAB: move between notes_section and subnotes_section
  490.       if current_window == 1:
  491.          current_window = tab(current_window,ss_cursor_vpos,ss_cursor_hpos)
  492.       elif current_window == 2:
  493.          current_window = tab(current_window,ns_cursor_vpos,ns_cursor_hpos)
  494.    elif key == curses.KEY_UP:
  495.       if current_window == 1:
  496.          ns_cursor_vpos,ns_cursor_hpos,current_note = navigate_notes_section(ns_cursor_vpos,ns_cursor_hpos,current_note,'up')
  497.       elif current_window == 2:
  498.          ss_cursor_vpos,ss_cursor_hpos,current_subnote = navigate_subnotes_section(ss_cursor_vpos,ss_cursor_hpos,current_subnote,'up')
  499.    elif key == curses.KEY_DOWN:
  500.       if current_window == 1:
  501.          ns_cursor_vpos,ns_cursor_hpos,current_note = navigate_notes_section(ns_cursor_vpos,ns_cursor_hpos,current_note,'down')
  502.       elif current_window == 2:
  503.          ss_cursor_vpos,ss_cursor_hpos,current_subnote = navigate_subnotes_section(ss_cursor_vpos,ss_cursor_hpos,current_subnote,'down')
  504.    elif key == curses.KEY_LEFT:
  505.       if current_window == 1:
  506.          ns_cursor_vpos,ns_cursor_hpos,current_note = navigate_notes_section(ns_cursor_vpos,ns_cursor_hpos,current_note,'left')
  507.       elif current_window == 2:
  508.          ss_cursor_vpos,ss_cursor_hpos,current_subnote = navigate_subnotes_section(ss_cursor_vpos,ss_cursor_hpos,current_subnote,'left')
  509.    elif key == curses.KEY_RIGHT:
  510.       if current_window == 1:
  511.          ns_cursor_vpos,ns_cursor_hpos,current_note = navigate_notes_section(ns_cursor_vpos,ns_cursor_hpos,current_note,'right')
  512.       elif current_window == 2:
  513.          ss_cursor_vpos,ss_cursor_hpos,current_subnote = navigate_subnotes_section(ss_cursor_vpos,ss_cursor_hpos,current_subnote,'right')
  514.    elif key == ord('\n'): # ENTER
  515.       build_chord(current_note,current_subnote)
  516.       build_scale(current_note,major_minor)
  517.       ss_cursor_vpos,ss_cursor_hpos,current_subnote = navigate_subnotes_section(ss_cursor_vpos,ss_cursor_hpos,current_subnote,'refresh')
  518.    elif key == curses.KEY_F1: # F1: major/minor(3) switch
  519.       if major_minor < 4:
  520.          major_minor = major_minor + 1
  521.          build_scale(current_note,major_minor)
  522.          ss_cursor_vpos,ss_cursor_hpos,current_subnote = navigate_subnotes_section(ss_cursor_vpos,ss_cursor_hpos,current_subnote,'refresh')
  523.       else:
  524.          major_minor = 1
  525.          build_scale(current_note,major_minor)
  526.          ss_cursor_vpos,ss_cursor_hpos,current_subnote = navigate_subnotes_section(ss_cursor_vpos,ss_cursor_hpos,current_subnote,'refresh')
  527.    elif key == curses.KEY_F2: # F2: switch pianokeys layout
  528.       caller_id = 2 # the caller-id for this function
  529.       if pianokeys == pianokeys_1:
  530.          piano_pikeys_layout = draw_piano(caller_id,0,bkeys_active,wkeys_active)
  531.          pianokeys = pianokeys_2
  532.       elif pianokeys == pianokeys_2:
  533.          piano_pikeys_layout = draw_piano(caller_id,1,bkeys_active,wkeys_active)
  534.          pianokeys = pianokeys_1
  535.       print_notes()
  536.       navigate_notes_section(ns_cursor_vpos,ns_cursor_hpos,current_note,'up') # to refresh the notes section
  537.       build_scale(current_note,major_minor)
  538.       build_chord(current_note,current_subnote)
  539.       ss_cursor_vpos,ss_cursor_hpos,current_subnote = navigate_subnotes_section(ss_cursor_vpos,ss_cursor_hpos,current_subnote,'refresh')
  540.    elif key == curses.KEY_F3: # F3: display of pianokeys/pckeys switch
  541.       caller_id = 3 # the caller-id for this function
  542.       piano_show_what = draw_piano(caller_id,piano_show_what,bkeys_active,wkeys_active)
  543.       build_chord(current_note,current_subnote)
  544.       ss_cursor_vpos,ss_cursor_hpos,current_subnote = navigate_subnotes_section(ss_cursor_vpos,ss_cursor_hpos,current_subnote,'refresh')
  545.  
  546. # _TODO: make it resizable.
  547. curses.endwin()