SHOW:
|
|
- or go back to the newest paste.
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 | - | scale,key_reference = build_scale(root,major_minor) |
296 | + | |
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() |