Beispiel #1
0
    def set_file_path(self, file_path):
        file_path = CU.safe_cast(file_path, pl.Path, None)

        if self._file_path != file_path:
            self._file_path = file_path
            # Reset modal view when the file path changed, just to be sure it's recreated when needed next time:
            self._modal_view = None
Beispiel #2
0
    def on_selected_path_filemanager(self, *args, **kwargs):
        """It will be called when you click on the file name
        or the catalog selection button.
        :type path: str;
        :param path: path to the selected directory or file;
        """

        path = CU.safe_cast(args[0][0], pl.Path, None)
        if path.is_file():
            # To make sure that whole parent directory is scanned for additional song-files:
            path = path.parents[0]

        path_found = False
        i = 0

        # On each invocation of this method the default path is prepended because at some point the user might change the tf_workspace_path, and then this change is automatically refreshed.
        scanned_song_locations = [pl.Path(CU.tfs.dic['tf_workspace_path'].value / CU.tfs.dic['RAW_MIDI_DIR_NAME'].value)] + self._list_additional_song_locations

        # Searching until first occurrence of possible duplicate:
        while not path_found and i < len(scanned_song_locations):
            if path.samefile(scanned_song_locations[i]): # path == scanned_song_locations[i]:
                path_found = True
                toast(f"{os.sep}{path.name}-folder is already searched")
            i = i+1

        if not path_found:
            # If the path is not found yet, it can be added, this whole operation was to avoid duplicates:
            self._list_additional_song_locations.append(path)
            toast(f"{path} added to search scope")

        self.refresh_list()
 def condense_note_pitch(note_number):
     """
     Returns the note pitch where a given note_number boils down to, regardless of the octave
     :param note_number: 'uncondensed' note_number (i.e. note_number which may be > 11).
     :return: the corresponding note_number < 11
     """
     note_number = CU.safe_cast(note_number, int, 0)
     return note_number % MusicTheoryCoreUtils.AMOUNT_DISTINCT_NOTES
Beispiel #4
0
 def set_repeat(self, loop_repeat):
     """
     Loop repeat option comes in very handy when you e.g. turn a sponsor-slideshow into a movie-file which should repeat at some points in the concert.
     :param loop_repeat:
     :return:
     """
     loop_repeat = CU.safe_cast(loop_repeat, bool, False)
     self._loop_repeat = loop_repeat
Beispiel #5
0
 def set_show_upside_down(self, show_upside_down):
     """
     Set boolean _show_upside_down, that will make the <LineupEntry> to be shown upside down. (This comes in handy when projecting vertically on the floor, so the image or clip to announce the next music-piece faces the audience)
     :param show_upside_down: bool
     :return:
     """
     show_upside_down = CU.safe_cast(show_upside_down, bool, False)
     self._show_upside_down = show_upside_down
Beispiel #6
0
 def set_songlevel_speedfactor(self, songlevel_speedfactor):
     """
     Set float _songlevel_speedfactor, to override the default overall_speed_factor inside the TF_Settigns at song level here.
     :param songlevel_speedfactor: bool
     :return:
     """
     songlevel_speedfactor = CU.safe_cast(songlevel_speedfactor, float, 1.0)
     self._songlevel_speedfactor = songlevel_speedfactor
Beispiel #7
0
 def set_mute_play_along(self, mute_play_along):
     """
     Set boolean _mute_play_along, to toggle whether synthetic MIDI file sound will be played out loud in concertmode.
     :param mute_play_along: bool
     :return:
     """
     mute_play_along = CU.safe_cast(mute_play_along, bool, True)
     self._mute_play_along = mute_play_along
 def set_file_path(self, file_path):
     """
     Setter _file_path
     :param file_path: _file_path
     :return:
     """
     file_path = CU.safe_cast(file_path, pl.Path, None)
     self._file_path = pl.Path(file_path)
Beispiel #9
0
 def set_mute_audio(self, mute_audio):
     """
     To mute the sound of a movie clip during playback.
     :param mute_audio:
     :return:
     """
     mute_audio = CU.safe_cast(mute_audio, bool, False)
     self._mute_audio = mute_audio
    def note_name_to_number(note_name):
        """
        Maps a human-readable note to its MIDI-encoded form. Supplied note_name should be formatted as {'C4', 'C#4/Db4', 'Db4/C#4', 'C#4', 'Db4', 'C#/Db4', 'Db/C#4'}.
        In other words, last character(s) must be devoted to denoting the octave. Midi now supports 10 octaves [0..9]
        :param note_name: string describing a note
        :return: MIDI-encoded note_number
        """
        note_name = CU.safe_cast(note_name, str, "")

        # Split on '/' to tell apart possible redundant namings:
        note_names = note_name.split("/")

        # Possible redundant namings are ignored by considering the last/default one:
        note_name = note_names[len(note_names) - 1]

        note_pitch_text, octave_text = CU.split_letters_from_digits(note_name)
        octave = CU.safe_cast(octave_text, int, 0)

        note_number = '-1'

        # Determine whether the note that has to be parsed is a black note or not.
        is_black_note = any((char in set('#b')) for char in note_pitch_text)

        # Save work in the next loop over the key-value pairs (parsing the note_pitch_text) by filtering the note_System:
        subdict_whites_or_blacks = {
            key: value
            for (key, value) in MusicTheoryCoreUtils.NOTE_SYSTEM.items()
            if ((key in MusicTheoryCoreUtils.WHITE_NOTES) == (
                not is_black_note))
        }

        # Map the retrieved note_pitch_text to a condensed_note_number:
        for key, value in subdict_whites_or_blacks.items():

            # As soon as the note is parsed exit the for loop:
            if note_pitch_text in value:
                note_number = key
                break

        if note_number != -1:
            # The reason why octave + 1 is multiplied with the amount of distinct notes rather than just octave is to meet the MIDI-standard. Apparently, an octave -1 is foreseen:
            note_number += MusicTheoryCoreUtils.AMOUNT_DISTINCT_NOTES * (
                octave + 1)

        return note_number
Beispiel #11
0
    def set_value(self, value):
        # Check if the type of the new value matches with the type of the default value, try safe_casting:
        if (isinstance(self._default_value, pl.Path)):
            # When it's a pl.Path, then the exportable FILE_SEP_TEXT should be replaced:
            value = str(value).replace(f"{CU.tfs.dic['FILE_SEP_TEXT'].value}", f"{os.sep}")
        if (isinstance(value, str)):
            value = CU.with_consistent_linesep(value)

        # The callback can do some extra checking of the value while its for instance still string, and order of doing the safe cast and calling the callback used to be the other way around, but the pathlib library uses other windows-lineseparator when casting back to string, but then it's not possible to omit an explanation
        if (self._callback_on_set is not None):
            processed_value = self._callback_on_set(value)
        else:
            processed_value = value

        if processed_value is not None:
            self._value = CU.safe_cast(processed_value, type(self._default_value), "")
        else:
            # The previous _value is left unchanged.
            toast(f"Value for setting \"{self.name}\" is not valid{os.linesep}Original value was left unchanged.")
Beispiel #12
0
    async def async_filter_list(self):
        """
        Filter the visual list on the provided search pattern.
        :return:
        """
        search_pattern = CU.safe_cast(self.ids.search_field.text, str, "")
        # print(f"search pattern is {search_pattern}")
        self.ids.rv.data = []

        for song in self._list:
            song_name = str(song.file_path.stem)
            if (len(search_pattern) == 0 or ((len(search_pattern) > 0) and (search_pattern.lower() in song_name.lower()))):

                self.ids.rv.data.append(
                    {
                        "viewclass": "SongRowView",
                        "list_obj": self,
                        "song_entry_obj": song,
                        "callback": None
                    }
                )
        await asynckivy.sleep(0)
    async def async_editable_filter_list(self):
        """
        Filter the visual editable_list on the provided search pattern.
        :return:
        """
        search_pattern = CU.safe_cast(self.ids.search_field.text, str, "")
        # print(f"search pattern is {search_pattern}")
        self.ids.rv.data = []

        for tfsetting in self._editable_list:
            # Make sure that user can also search by entering a snippet of the value or the description.
            setting_name = f"{tfsetting.name}{str(tfsetting.value)}{str(tfsetting.description)}"
            if (len(search_pattern) == 0
                    or ((len(search_pattern) > 0) and
                        (search_pattern.lower() in setting_name.lower()))):

                self.ids.rv.data.append({
                    "viewclass": "TFSettingRowView",
                    "list_obj": self,
                    "tfsetting_obj": tfsetting,
                    "callback": None
                })
        await asynckivy.sleep(0)
Beispiel #14
0
 def set_list(self, list):
     list = CU.safe_cast(list, self._list.__class__, "")
     self._list = list
Beispiel #15
0
    def __init__(self, file_path, **kwargs):

        self._file_path = CU.safe_cast(file_path, pl.Path, None)

        # I chose to store the modal view locally when created, so it does not need to be created over and over again:
        self._modal_view = None
Beispiel #16
0
 def set_description(self, description):
     description = CU.safe_cast(description, str, "")
     self._description = description
 def set_editable_list(self, editable_list):
     editable_list = CU.safe_cast(editable_list,
                                  self._editable_list.__class__, "")
     self._editable_list = editable_list
Beispiel #18
0
 def set_name(self, name):
     name = CU.safe_cast(name, str, "")
     self._name = name