def __init__(self, teacher): abstract.IntervalGui.__init__(self, teacher) self.std_buttons_add(('give_up', self.give_up)) ############### # config_grid # ############### self.g_mici = MultipleIntervalConfigWidget(self.m_exname, self.g_config_grid, 0, 0) self.add_lock_to_key_gui(row=4) self._add_auto_new_question_gui(row=5) self._create_select_inputwidget_gui(row=6) self.g_config_grid.show_all() ############## # statistics # ############## self.setup_statisticsviewer(statisticsviewer.StatisticsViewer, _("Melodic interval")) self.select_inputwidget() def _f(watchvar): # The variables being watched by this function will change # when we switch lesson files or when we are in expert mode and # the user configures the exercise manually. We only have to run # end|start_exercise here in expert mode because it is called # automatically when we change lesson file. if self.m_t.m_custom_mode: self.on_end_practise() for i in range(self.get_int('maximum_number_of_intervals')): self.add_watch('ask_for_intervals_%i' % i, _f) self.add_watch('number_of_intervals', _f)
def __init__(self, teacher): abstract.Gui.__init__(self, teacher) ################ # practise_box # ################ self.g_score_displayer = mpd.MusicDisplayer() self.practise_box.pack_start(self.g_score_displayer, True, True, 0) self.g_score_displayer.clear() b1 = gu.bHBox(self.practise_box, False) self.g_new_interval_correct = gu.bButton( b1, _("_New interval,\nlast was correct"), self.new_question) self.g_new_interval_wrong = gu.bButton( b1, _("New interval,\nlast was _wrong"), self.new_last_was_wrong) self.g_new_interval = gu.bButton(b1, _("_New interval"), self.new_question) self.g_new_interval_wrong.set_sensitive(False) self.g_repeat_tonika = gu.bButton( self.action_area, _("_Repeat first tone"), lambda _o, self=self: self.m_t.play_first_tone()) self.g_repeat_tonika.set_sensitive(False) self.g_play_answer = gu.bButton( self.action_area, _("_Play answer"), lambda _o, self=self: self.m_t.play_question()) self.g_play_answer.set_sensitive(False) self.g_repeat_last_tone = gu.bButton( self.action_area, _("Play _last tone"), lambda _o, self=self: self.m_t.play_last_tone()) self.g_repeat_last_tone.set_sensitive(False) self.practise_box.show_all() self.g_new_interval_correct.hide() self.g_new_interval_wrong.hide() ############### # config_grid # ############### self.g_mici = MultipleIntervalConfigWidget(self.m_exname, self.g_config_grid, 0, 0) ############### # statistics ############### self.setup_statisticsviewer(statisticsviewer.StatisticsViewer, _("Sing interval"))
def __init__(self, teacher): abstract.Gui.__init__(self, teacher) ################ # practise_box # ################ self.g_score_displayer = mpd.musicdisplayer.MusicDisplayer() self.practise_box.pack_start(self.g_score_displayer) self.g_score_displayer.clear() b1 = gu.bHBox(self.practise_box, False) self.g_new_interval_correct = gu.bButton(b1, _("_New interval,\nlast was correct"), self.new_question) self.g_new_interval_wrong = gu.bButton(b1, _("New interval,\nlast was _wrong"), self.new_last_was_wrong) self.g_new_interval = gu.bButton(b1, _("_New interval"), self.new_question) self.g_new_interval_wrong.set_sensitive(False) self.g_repeat_tonika = gu.bButton(self.action_area, _("_Repeat first tone"), lambda _o, self=self: self.m_t.play_first_tone()) self.g_repeat_tonika.set_sensitive(False) self.g_play_answer = gu.bButton(self.action_area, _("_Play answer"), lambda _o, self=self: self.m_t.play_question()) self.g_play_answer.set_sensitive(False) self.g_repeat_last_tone = gu.bButton(self.action_area, _("Play _last tone"), lambda _o, self=self: self.m_t.play_last_tone()) self.g_repeat_last_tone.set_sensitive(False) self.practise_box.show_all() self.g_new_interval_correct.hide() self.g_new_interval_wrong.hide() ############## # config_box # ############## self.g_mici = MultipleIntervalConfigWidget(self.m_exname) self.config_box.pack_start(self.g_mici, False) self.config_box.show_all() ############### # statistics ############### self.setup_statisticsviewer( statisticsviewer.PercentagesStatisticsViewer, _("Sing interval"))
class Gui(abstract.Gui): lesson_heading = _("Sing the interval") def __init__(self, teacher): abstract.Gui.__init__(self, teacher) ################ # practise_box # ################ self.g_score_displayer = mpd.MusicDisplayer() self.practise_box.pack_start(self.g_score_displayer, True, True, 0) self.g_score_displayer.clear() b1 = gu.bHBox(self.practise_box, False) self.g_new_interval_correct = gu.bButton( b1, _("_New interval,\nlast was correct"), self.new_question) self.g_new_interval_wrong = gu.bButton( b1, _("New interval,\nlast was _wrong"), self.new_last_was_wrong) self.g_new_interval = gu.bButton(b1, _("_New interval"), self.new_question) self.g_new_interval_wrong.set_sensitive(False) self.g_repeat_tonika = gu.bButton( self.action_area, _("_Repeat first tone"), lambda _o, self=self: self.m_t.play_first_tone()) self.g_repeat_tonika.set_sensitive(False) self.g_play_answer = gu.bButton( self.action_area, _("_Play answer"), lambda _o, self=self: self.m_t.play_question()) self.g_play_answer.set_sensitive(False) self.g_repeat_last_tone = gu.bButton( self.action_area, _("Play _last tone"), lambda _o, self=self: self.m_t.play_last_tone()) self.g_repeat_last_tone.set_sensitive(False) self.practise_box.show_all() self.g_new_interval_correct.hide() self.g_new_interval_wrong.hide() ############### # config_grid # ############### self.g_mici = MultipleIntervalConfigWidget(self.m_exname, self.g_config_grid, 0, 0) ############### # statistics ############### self.setup_statisticsviewer(statisticsviewer.StatisticsViewer, _("Sing interval")) def _new_question(self): try: r = self.m_t.new_question(self.get_string('user/lowest_pitch'), self.get_string('user/highest_pitch')) except Teacher.ConfigureException as e: solfege.win.display_error_message2( _("Exercise configuration problem"), str(e)) return if r == Teacher.OK: self.m_t.play_first_tone() self.g_score_displayer.display_score(self.m_t.get_question()) self.g_new_interval_wrong.set_sensitive(True) self.g_repeat_tonika.set_sensitive(True) self.g_play_answer.set_sensitive(True) self.g_repeat_last_tone.set_sensitive(True) self.g_new_interval_correct.grab_focus() elif r == Teacher.ERR_CONFIGURE: self.g_repeat_tonika.set_sensitive(False) self.g_play_answer.set_sensitive(False) self.g_repeat_last_tone.set_sensitive(False) solfege.win.display_error_message( _("The exercise has to be better configured.\nClick 'Reset to default values' on the config\npage if you don't know how to do this." )) self.g_score_displayer.clear() return r def on_start_practise(self): # First, we have to empty the cfg database because we will # copy the values from the lesson header. for i in range(self.get_int('maximum_number_of_intervals')): self.set_list('ask_for_intervals_%i' % i, []) # If ask_for_intervals_0 is not set, then we run in custom_mode # where the user configure the exercise on her own. if self.m_t.m_P.header.ask_for_intervals_0: for i in range(self.get_int('maximum_number_of_intervals')): if 'ask_for_intervals_%i' % i in self.m_t.m_P.header: self.set_list( 'ask_for_intervals_%i' % i, self.m_t.m_P.header['ask_for_intervals_%i' % i]) else: break self.set_int('number_of_intervals', i) # This exercise will be in expert mode when the lesson file # does not specify which questions to ask. It will ignore # the setting in the preferences window self.m_t.m_custom_mode = bool( not self.m_t.m_P.header.ask_for_intervals_0) super(Gui, self).on_start_practise() if self.m_t.m_custom_mode: self.g_mici.show() else: self.g_mici.hide() self.m_t.m_statistics.reset_session() self.g_statview.g_heading.set_text( "%s - %s" % (_("Sing interval"), self.m_t.m_P.header.title)) self.handle_config_grid_visibility() self.g_new_interval.grab_focus() self.g_new_interval_correct.hide() self.g_new_interval_wrong.hide() def on_end_practise(self): self.g_new_interval.show() self.g_repeat_tonika.set_sensitive(False) self.g_play_answer.set_sensitive(False) self.g_repeat_last_tone.set_sensitive(False) self.m_t.end_practise() self.g_score_displayer.clear() def new_last_was_wrong(self, widget=None): if self.m_t.q_status == self.QSTATUS_NEW: self.m_t.guessed_wrong() if solfege.app.m_test_mode and self.m_t.m_P.is_test_complete(): self.do_test_complete() return self._new_question() def new_question(self, widget=None): # called by 'new last was correct' and from # teacher when we get a new question automatically. if self.m_t.q_status == self.QSTATUS_NEW: self.m_t.guessed_correct() if solfege.app.m_test_mode and self.m_t.m_P.is_test_complete(): self.do_test_complete() return try: r = self._new_question() except Exception as e: if not self.standard_exception_handler(e): raise return if r == Teacher.OK: self.g_new_interval.hide() self.g_new_interval_correct.show() self.g_new_interval_wrong.show() def enter_test_mode(self): self.m_saved_q_auto = self.get_bool('new_question_automatically') self.m_saved_s_new = self.get_float('seconds_before_new_question') self.set_bool('new_question_automatically', True) self.set_float('seconds_before_new_question', 0.5) self.m_t.enter_test_mode() self.g_new_interval.set_label(_("_Start test")) self.g_new_interval_correct.hide() self.g_new_interval_wrong.hide() self.g_cancel_test.show() def exit_test_mode(self): self.set_bool('new_question_automatically', self.m_saved_q_auto) self.set_float('seconds_before_new_question', self.m_saved_s_new) self.m_t.exit_test_mode() self.g_new_interval.show() self.g_new_interval.set_label(_("_New interval")) self.g_new_interval_wrong.hide() self.g_new_interval_correct.hide()
class Gui(abstract.Gui): lesson_heading = _("Sing the interval") def __init__(self, teacher): abstract.Gui.__init__(self, teacher) ################ # practise_box # ################ self.g_score_displayer = mpd.MusicDisplayer() self.practise_box.pack_start(self.g_score_displayer, True, True, 0) self.g_score_displayer.clear() b1 = gu.bHBox(self.practise_box, False) self.g_new_interval_correct = gu.bButton(b1, _("_New interval,\nlast was correct"), self.new_question) self.g_new_interval_wrong = gu.bButton(b1, _("New interval,\nlast was _wrong"), self.new_last_was_wrong) self.g_new_interval = gu.bButton(b1, _("_New interval"), self.new_question) self.g_new_interval_wrong.set_sensitive(False) self.g_repeat_tonika = gu.bButton(self.action_area, _("_Repeat first tone"), lambda _o, self=self: self.m_t.play_first_tone()) self.g_repeat_tonika.set_sensitive(False) self.g_play_answer = gu.bButton(self.action_area, _("_Play answer"), lambda _o, self=self: self.m_t.play_question()) self.g_play_answer.set_sensitive(False) self.g_repeat_last_tone = gu.bButton(self.action_area, _("Play _last tone"), lambda _o, self=self: self.m_t.play_last_tone()) self.g_repeat_last_tone.set_sensitive(False) self.practise_box.show_all() self.g_new_interval_correct.hide() self.g_new_interval_wrong.hide() ############### # config_grid # ############### self.g_mici = MultipleIntervalConfigWidget(self.m_exname, self.g_config_grid, 0, 0) ############### # statistics ############### self.setup_statisticsviewer( statisticsviewer.StatisticsViewer, _("Sing interval")) def _new_question(self): try: r = self.m_t.new_question(self.get_string('user/lowest_pitch'), self.get_string('user/highest_pitch')) except Teacher.ConfigureException as e: solfege.win.display_error_message2(_("Exercise configuration problem"), str(e)) return if r == Teacher.OK: self.m_t.play_first_tone() self.g_score_displayer.display_score(self.m_t.get_question()) self.g_new_interval_wrong.set_sensitive(True) self.g_repeat_tonika.set_sensitive(True) self.g_play_answer.set_sensitive(True) self.g_repeat_last_tone.set_sensitive(True) self.g_new_interval_correct.grab_focus() elif r == Teacher.ERR_CONFIGURE: self.g_repeat_tonika.set_sensitive(False) self.g_play_answer.set_sensitive(False) self.g_repeat_last_tone.set_sensitive(False) solfege.win.display_error_message(_("The exercise has to be better configured.\nClick 'Reset to default values' on the config\npage if you don't know how to do this.")) self.g_score_displayer.clear() return r def on_start_practise(self): # First, we have to empty the cfg database because we will # copy the values from the lesson header. for i in range(self.get_int('maximum_number_of_intervals')): self.set_list('ask_for_intervals_%i' % i, []) # If ask_for_intervals_0 is not set, then we run in custom_mode # where the user configure the exercise on her own. if self.m_t.m_P.header.ask_for_intervals_0: for i in range(self.get_int('maximum_number_of_intervals')): if 'ask_for_intervals_%i' % i in self.m_t.m_P.header: self.set_list('ask_for_intervals_%i' % i, self.m_t.m_P.header['ask_for_intervals_%i' % i]) else: break self.set_int('number_of_intervals', i) # This exercise will be in expert mode when the lesson file # does not specify which questions to ask. It will ignore # the setting in the preferences window self.m_t.m_custom_mode = bool( not self.m_t.m_P.header.ask_for_intervals_0) super(Gui, self).on_start_practise() if self.m_t.m_custom_mode: self.g_mici.show() else: self.g_mici.hide() self.m_t.m_statistics.reset_session() self.g_statview.g_heading.set_text("%s - %s" % (_("Sing interval"), self.m_t.m_P.header.title)) self.handle_config_grid_visibility() self.g_new_interval.grab_focus() self.g_new_interval_correct.hide() self.g_new_interval_wrong.hide() def on_end_practise(self): self.g_new_interval.show() self.g_repeat_tonika.set_sensitive(False) self.g_play_answer.set_sensitive(False) self.g_repeat_last_tone.set_sensitive(False) self.m_t.end_practise() self.g_score_displayer.clear() def new_last_was_wrong(self, widget=None): if self.m_t.q_status == self.QSTATUS_NEW: self.m_t.guessed_wrong() if solfege.app.m_test_mode and self.m_t.m_P.is_test_complete(): self.do_test_complete() return self._new_question() def new_question(self, widget=None): # called by 'new last was correct' and from # teacher when we get a new question automatically. if self.m_t.q_status == self.QSTATUS_NEW: self.m_t.guessed_correct() if solfege.app.m_test_mode and self.m_t.m_P.is_test_complete(): self.do_test_complete() return try: r = self._new_question() except Exception as e: if not self.standard_exception_handler(e): raise return if r == Teacher.OK: self.g_new_interval.hide() self.g_new_interval_correct.show() self.g_new_interval_wrong.show() def enter_test_mode(self): self.m_saved_q_auto = self.get_bool('new_question_automatically') self.m_saved_s_new = self.get_float('seconds_before_new_question') self.set_bool('new_question_automatically', True) self.set_float('seconds_before_new_question', 0.5) self.m_t.enter_test_mode() self.g_new_interval.set_label(_("_Start test")) self.g_new_interval_correct.hide() self.g_new_interval_wrong.hide() self.g_cancel_test.show() def exit_test_mode(self): self.set_bool('new_question_automatically', self.m_saved_q_auto) self.set_float('seconds_before_new_question', self.m_saved_s_new) self.m_t.exit_test_mode() self.g_new_interval.show() self.g_new_interval.set_label(_("_New interval")) self.g_new_interval_wrong.hide() self.g_new_interval_correct.hide()
class Gui(abstract.IntervalGui): lesson_heading = _("Identify the interval") def __init__(self, teacher): abstract.IntervalGui.__init__(self, teacher) self.std_buttons_add(('give_up', self.give_up)) ############### # config_grid # ############### self.g_mici = MultipleIntervalConfigWidget(self.m_exname, self.g_config_grid, 0, 0) self.add_lock_to_key_gui(row=4) self._add_auto_new_question_gui(row=5) self._create_select_inputwidget_gui(row=6) self.g_config_grid.show_all() ############## # statistics # ############## self.setup_statisticsviewer(statisticsviewer.StatisticsViewer, _("Melodic interval")) self.select_inputwidget() def _f(watchvar): # The variables being watched by this function will change # when we switch lesson files or when we are in expert mode and # the user configures the exercise manually. We only have to run # end|start_exercise here in expert mode because it is called # automatically when we change lesson file. if self.m_t.m_custom_mode: self.on_end_practise() for i in range(self.get_int('maximum_number_of_intervals')): self.add_watch('ask_for_intervals_%i' % i, _f) self.add_watch('number_of_intervals', _f) def give_up(self, _o=None): if self.m_t.q_status == self.QSTATUS_WRONG: if len(self.m_t.m_question) == 1: s = utils.int_to_intervalname(self.m_t.m_question[0], False, True) else: s = "+".join([utils.int_to_intervalname(q, True, True) for q in self.m_t.m_question]) self.g_flashbar.push(s) self.m_t.give_up() self.std_buttons_give_up() self.g_input.mark_note(int(self.m_t.m_tonika + self.m_t.m_question[0]), 2) def get_interval_input_list(self): v = [] for x in range(self.get_int('number_of_intervals')): for i in self.get_list('ask_for_intervals_%i' % x): if not (abs(i) in v): v.append(abs(i)) v.sort() return v def click_on_interval(self, mouse_button, interval, midi_int): """The key bindings are also directed here. """ if mouse_button == 3 and not solfege.app.m_test_mode \ and self.get_int('number_of_intervals') == 1: if not self.m_t.m_tonika: return i = mpd.Interval() if (not midi_int # buttons interface does not set midi_int. And # since it assumes all intervals go up, we have # to check and set the direction. and self.m_t.m_question[0] < 0): i.set_from_int(-interval) else: i.set_from_int(interval) n = self.m_t.m_tonika + i track = utils.new_track() track.note(4, self.m_t.m_tonika.semitone_pitch()) track.note(4, n.semitone_pitch()) soundcard.synth.play_track(track) return if mouse_button not in (1, self.keyboard_accel): return if solfege.app.m_test_mode and self.m_t.q_status == self.QSTATUS_NO: self.g_flashbar.flash(_("Click 'Start test' to begin.")) return if solfege.app.m_test_mode: self.g_new.hide() if self.m_t.q_status == self.QSTATUS_NO: self.g_flashbar.flash(_("Click 'New interval' to begin.")) return if midi_int: # midi_int is only set when we use some of the instrument widgets, # not when we use the buttons interface. utils.play_note(4, midi_int) if self.m_t.q_status == self.QSTATUS_GIVE_UP: return if self.m_t.q_status == self.QSTATUS_SOLVED: self.g_flashbar.flash(_("You have already identified this interval")) return if not (mpd.interval.min_interval < interval <= mpd.interval.max_interval): self.g_flashbar.flash(_("Ignoring intervals greater than double octave.")) self.g_input.forget_last_tone() return self.m_answer.append(interval) d = self.m_t.m_question[len(self.m_answer) - 1] md = d // d if self.g_input.know_directions(): md = 1 if not self.msg: self.msg = utils.int_to_intervalname(interval * md, 1, 1) + "+ ..." else: self.msg = self.msg[:-4] self.msg = self.msg + utils.int_to_intervalname(interval * md, 1, 1) + "+ ..." self.g_flashbar.push(self.msg) if len(self.m_answer) == self.m_number_of_intervals_in_question: if self.m_t.guess_answer(self.m_answer, self.g_input.know_directions()): self.g_flashbar.clear() self.g_flashbar.flash(_("Correct")) self.std_buttons_answer_correct() else: self.g_flashbar.clear() self.g_flashbar.flash(_("Wrong")) if self.get_bool("config/auto_repeat_question_if_wrong_answer"): self.m_t.play_question() self.std_buttons_answer_wrong() self.m_answer = [] self.g_input.set_first_note(self.m_t.m_tonika) self.msg = "" if solfege.app.m_test_mode and self.m_t.m_P.is_test_complete(): self.do_test_complete() return def new_question(self, _o=None): self.msg = "" self.m_number_of_intervals_in_question \ = self.get_int('number_of_intervals') self.m_answer = [] if hasattr(self.g_input, 'use_users_vocal_range'): low = self.get_string('user/lowest_pitch') high = self.get_string('user/highest_pitch') else: low = self.g_input.m_lowest_tone high = self.g_input.m_highest_tone try: ret = self.m_t.new_question(low, high) except Teacher.ConfigureException as e: self.g_flashbar.clear() solfege.win.display_error_message2(_("Exercise configuration problem"), str(e)) self.g_repeat.set_sensitive(False) else: if ret == Teacher.ERR_PICKY: self.g_flashbar.flash(_("You have to solve this question first.")) self.g_input.set_first_note(self.m_t.m_tonika) def exception_cleanup(): self.m_t.end_practise() self.std_buttons_exception_cleanup() try: self.m_t.play_question() except Exception as e: if not self.standard_exception_handler(e, exception_cleanup): raise return self.std_buttons_new_question() self.g_flashbar.clear() # inputwidget 0 is always the buttons. if self.get_int('inputwidget') == 0: self.g_input.grab_focus_first_sensitive_button() def on_start_practise(self): self.m_t.start_practise() super(Gui, self).on_start_practise() if self.m_t.m_custom_mode: self.g_mici.show() else: self.m_t.m_statistics.reset_session() self.g_mici.hide() self.g_statview.g_heading.set_text("%s - %s" % (_("Melodic interval"), self.m_t.m_P.header.title)) self.std_buttons_start_practise() if solfege.app.m_test_mode: self.g_flashbar.delayed_flash(self.short_delay, _("Click 'Start test' to begin.")) else: self.g_flashbar.delayed_flash(self.short_delay, _("Click 'New interval' to begin.")) def on_end_practise(self): self.m_t.end_practise() self.std_buttons_end_practise() self.g_input.clear() self.g_flashbar.clear() def enter_test_mode(self): self.m_saved_q_auto = self.get_bool('new_question_automatically') self.m_saved_s_new = self.get_float('seconds_before_new_question') self.set_bool('new_question_automatically', True) self.set_float('seconds_before_new_question', 0.5) self.m_t.enter_test_mode() self.g_new.set_label(_("_Start test")) self.g_cancel_test.show() self.g_give_up.hide() def exit_test_mode(self): self.set_bool('new_question_automatically', self.m_saved_q_auto) self.set_float('seconds_before_new_question', self.m_saved_s_new) self.m_t.exit_test_mode() self.g_new.show() self.g_new.set_label(_("_New interval")) self.g_give_up.show()
class Gui(abstract.IntervalGui): lesson_heading = _("Identify the interval") def __init__(self, teacher): abstract.IntervalGui.__init__(self, teacher) self.std_buttons_add(('give_up', self.give_up)) ############### # config_grid # ############### self.g_mici = MultipleIntervalConfigWidget(self.m_exname, self.g_config_grid, 0, 0) self.add_lock_to_key_gui(row=4) self._add_auto_new_question_gui(row=5) self._create_select_inputwidget_gui(row=6) self.g_config_grid.show_all() ############## # statistics # ############## self.setup_statisticsviewer(statisticsviewer.StatisticsViewer, _("Melodic interval")) self.select_inputwidget() def _f(watchvar): # The variables being watched by this function will change # when we switch lesson files or when we are in expert mode and # the user configures the exercise manually. We only have to run # end|start_exercise here in expert mode because it is called # automatically when we change lesson file. if self.m_t.m_custom_mode: self.on_end_practise() for i in range(self.get_int('maximum_number_of_intervals')): self.add_watch('ask_for_intervals_%i' % i, _f) self.add_watch('number_of_intervals', _f) def give_up(self, _o=None): if self.m_t.q_status == self.QSTATUS_WRONG: if len(self.m_t.m_question) == 1: s = utils.int_to_intervalname(self.m_t.m_question[0], False, True) else: s = "+".join([ utils.int_to_intervalname(q, True, True) for q in self.m_t.m_question ]) self.g_flashbar.push(s) self.m_t.give_up() self.std_buttons_give_up() self.g_input.mark_note( int(self.m_t.m_tonika + self.m_t.m_question[0]), 2) def get_interval_input_list(self): v = [] for x in range(self.get_int('number_of_intervals')): for i in self.get_list('ask_for_intervals_%i' % x): if not (abs(i) in v): v.append(abs(i)) v.sort() return v def click_on_interval(self, mouse_button, interval, midi_int): """The key bindings are also directed here. """ if mouse_button == 3 and not solfege.app.m_test_mode \ and self.get_int('number_of_intervals') == 1: if not self.m_t.m_tonika: return i = mpd.Interval() if (not midi_int # buttons interface does not set midi_int. And # since it assumes all intervals go up, we have # to check and set the direction. and self.m_t.m_question[0] < 0): i.set_from_int(-interval) else: i.set_from_int(interval) n = self.m_t.m_tonika + i track = utils.new_track() track.note(4, self.m_t.m_tonika.semitone_pitch()) track.note(4, n.semitone_pitch()) soundcard.synth.play_track(track) return if mouse_button not in (1, self.keyboard_accel): return if solfege.app.m_test_mode and self.m_t.q_status == self.QSTATUS_NO: self.g_flashbar.flash(_("Click 'Start test' to begin.")) return if solfege.app.m_test_mode: self.g_new.hide() if self.m_t.q_status == self.QSTATUS_NO: self.g_flashbar.flash(_("Click 'New interval' to begin.")) return if midi_int: # midi_int is only set when we use some of the instrument widgets, # not when we use the buttons interface. utils.play_note(4, midi_int) if self.m_t.q_status == self.QSTATUS_GIVE_UP: return if self.m_t.q_status == self.QSTATUS_SOLVED: self.g_flashbar.flash( _("You have already identified this interval")) return if not (mpd.interval.min_interval < interval <= mpd.interval.max_interval): self.g_flashbar.flash( _("Ignoring intervals greater than double octave.")) self.g_input.forget_last_tone() return self.m_answer.append(interval) d = self.m_t.m_question[len(self.m_answer) - 1] md = d // d if self.g_input.know_directions(): md = 1 if not self.msg: self.msg = utils.int_to_intervalname(interval * md, 1, 1) + "+ ..." else: self.msg = self.msg[:-4] self.msg = self.msg + utils.int_to_intervalname( interval * md, 1, 1) + "+ ..." self.g_flashbar.push(self.msg) if len(self.m_answer) == self.m_number_of_intervals_in_question: if self.m_t.guess_answer(self.m_answer, self.g_input.know_directions()): self.g_flashbar.clear() self.g_flashbar.flash(_("Correct")) self.std_buttons_answer_correct() else: self.g_flashbar.clear() self.g_flashbar.flash(_("Wrong")) if self.get_bool( "config/auto_repeat_question_if_wrong_answer"): self.m_t.play_question() self.std_buttons_answer_wrong() self.m_answer = [] self.g_input.set_first_note(self.m_t.m_tonika) self.msg = "" if solfege.app.m_test_mode and self.m_t.m_P.is_test_complete(): self.do_test_complete() return def new_question(self, _o=None): self.msg = "" self.m_number_of_intervals_in_question \ = self.get_int('number_of_intervals') self.m_answer = [] if hasattr(self.g_input, 'use_users_vocal_range'): low = self.get_string('user/lowest_pitch') high = self.get_string('user/highest_pitch') else: low = self.g_input.m_lowest_tone high = self.g_input.m_highest_tone try: ret = self.m_t.new_question(low, high) except Teacher.ConfigureException as e: self.g_flashbar.clear() solfege.win.display_error_message2( _("Exercise configuration problem"), str(e)) self.g_repeat.set_sensitive(False) else: if ret == Teacher.ERR_PICKY: self.g_flashbar.flash( _("You have to solve this question first.")) self.g_input.set_first_note(self.m_t.m_tonika) def exception_cleanup(): self.m_t.end_practise() self.std_buttons_exception_cleanup() try: self.m_t.play_question() except Exception as e: if not self.standard_exception_handler(e, exception_cleanup): raise return self.std_buttons_new_question() self.g_flashbar.clear() # inputwidget 0 is always the buttons. if self.get_int('inputwidget') == 0: self.g_input.grab_focus_first_sensitive_button() def on_start_practise(self): self.m_t.start_practise() super(Gui, self).on_start_practise() if self.m_t.m_custom_mode: self.g_mici.show() else: self.m_t.m_statistics.reset_session() self.g_mici.hide() self.g_statview.g_heading.set_text( "%s - %s" % (_("Melodic interval"), self.m_t.m_P.header.title)) self.std_buttons_start_practise() if solfege.app.m_test_mode: self.g_flashbar.delayed_flash(self.short_delay, _("Click 'Start test' to begin.")) else: self.g_flashbar.delayed_flash(self.short_delay, _("Click 'New interval' to begin.")) def on_end_practise(self): self.m_t.end_practise() self.std_buttons_end_practise() self.g_input.clear() self.g_flashbar.clear() def enter_test_mode(self): self.m_saved_q_auto = self.get_bool('new_question_automatically') self.m_saved_s_new = self.get_float('seconds_before_new_question') self.set_bool('new_question_automatically', True) self.set_float('seconds_before_new_question', 0.5) self.m_t.enter_test_mode() self.g_new.set_label(_("_Start test")) self.g_cancel_test.show() self.g_give_up.hide() def exit_test_mode(self): self.set_bool('new_question_automatically', self.m_saved_q_auto) self.set_float('seconds_before_new_question', self.m_saved_s_new) self.m_t.exit_test_mode() self.g_new.show() self.g_new.set_label(_("_New interval")) self.g_give_up.show()