diff --git a/src/scratchtocatrobat/converter/converter.py b/src/scratchtocatrobat/converter/converter.py index d9ccff37..ee77ece9 100644 --- a/src/scratchtocatrobat/converter/converter.py +++ b/src/scratchtocatrobat/converter/converter.py @@ -32,6 +32,7 @@ from org.catrobat.catroid import ProjectManager import org.catrobat.catroid.common as catcommon import org.catrobat.catroid.content as catbase +from org.catrobat.catroid.content.bricks.brickspinner import PickableDrum from org.catrobat.catroid.ui.fragment import SpriteFactory import org.catrobat.catroid.content.bricks as catbricks import org.catrobat.catroid.formulaeditor as catformula @@ -438,6 +439,9 @@ class _ScratchToCatrobat(object): "changeVolumeBy:": catbricks.ChangeVolumeByNBrick, "setVolumeTo:": catbricks.SetVolumeToBrick, + # music + "drum:duration:elapsed:from:": catbricks.PlayDrumForBeatsBrick, + # bubble bricks "say:duration:elapsed:from:": catbricks.SayForBubbleBrick, "say:": catbricks.SayBubbleBrick, @@ -2858,6 +2862,7 @@ def _convert_delete_line_of_list_block(self): deleteItemBrick.setFormulaWithBrickField(catbricks.Brick.BrickField.LIST_DELETE_ITEM, index_formula) return deleteItemBrick + if position == "all": loop_condition_formula = catrobat.create_formula_with_value(self._converted_helper_brick_or_formula_element([list_name], "lineCountOfList:")) catr_loop_start_brick = catbricks.RepeatBrick(loop_condition_formula) @@ -3436,3 +3441,21 @@ def _convert_note_block(self): if isinstance(arg, (str, unicode)) or isinstance(arg, catformula.Formula): return self.CatrobatClass(arg) log.warn("Invalid argument for NoteBrick: " + arg) + + @_register_handler(_block_name_to_handler_map, "drum:duration:elapsed:from:") + def _convert_play_drum_for_beats_block(self): + [drum, duration] = self.arguments + + try: + drum_int = int(drum) + except ValueError: + log.debug("There is no integer in DRUM") + return + + drum_selection = PickableDrum.values()[drum_int - 1] + assert drum_selection is not None + + play_drum_brick = self.CatrobatClass(catformula.Formula(duration)) + play_drum_brick.drumSelection = drum_selection + + return play_drum_brick diff --git a/src/scratchtocatrobat/converter/test_converter.py b/src/scratchtocatrobat/converter/test_converter.py index 56afa664..55a9b391 100644 --- a/src/scratchtocatrobat/converter/test_converter.py +++ b/src/scratchtocatrobat/converter/test_converter.py @@ -31,6 +31,7 @@ import org.catrobat.catroid.content.bricks.Brick as catbasebrick import org.catrobat.catroid.formulaeditor as catformula import org.catrobat.catroid.formulaeditor.FormulaElement.ElementType as catElementType +from scratchtocatrobat.scratch.scratch3visitor.scratch2_json_format import Scratch3_2Opcodes as opcodes import xml.etree.cElementTree as ET from scratchtocatrobat.converter import catrobat, converter, mediaconverter @@ -1417,6 +1418,18 @@ def test_can_convert_insert_at_random_position_in_list_block(self): assert formula_tree_value.leftChild == None assert formula_tree_value.rightChild == None + # drum:duration:elapsed:from: + def test_can_convert_play_drum_for_beats_block(self): + drum = 2 + beats = 1.0 + scratch_block = ["drum:duration:elapsed:from:", drum, beats] + [catr_brick] = self.block_converter._catrobat_bricks_from(scratch_block, DUMMY_CATR_SPRITE) + assert isinstance(catr_brick, catbricks.PlayDrumForBeatsBrick) + formula_tree_list_delete_item = catr_brick.getFormulaWithBrickField(catbasebrick.BrickField.PLAY_DRUM).formulaTree # @UndefinedVariable + assert formula_tree_list_delete_item.type == catformula.FormulaElement.ElementType.NUMBER + assert formula_tree_list_delete_item.value == str(beats) + assert catr_brick.drumSelection.value == 35 + # deleteLine:ofList: def test_can_convert_delete_line_from_list_by_index_block(self): index = 2 @@ -1427,6 +1440,7 @@ def test_can_convert_delete_line_from_list_by_index_block(self): assert formula_tree_list_delete_item.type == catformula.FormulaElement.ElementType.NUMBER assert formula_tree_list_delete_item.value == str(index) + # deleteLine:ofList: def test_can_convert_delete_last_line_from_list_block(self): scratch_block = ["deleteLine:ofList:", "last", self._name_of_test_list] diff --git a/src/scratchtocatrobat/scratch/scratch3visitor/blockmapping.py b/src/scratchtocatrobat/scratch/scratch3visitor/blockmapping.py index 2a7878bb..b7f023d5 100644 --- a/src/scratchtocatrobat/scratch/scratch3visitor/blockmapping.py +++ b/src/scratchtocatrobat/scratch/scratch3visitor/blockmapping.py @@ -1,4 +1,6 @@ -import looks, motion, event, sensing, sound, operator, control, data, pen +import looks, motion, event, sensing, sound, operator, control, data, pen, music +from scratchtocatrobat.scratch.scratch3visitor.scratch2_json_format import Scratch3_2Opcodes as opcodes + visitormap = { ### event blocks #### "event_whenflagclicked" : event.visitWhenflagclicked, #tested @@ -167,5 +169,8 @@ "pen_setPenShadeToNumber" : pen.visitSetPenShadeToNumber, #tested "pen_changePenShadeBy" : pen.visitChangePenShadeByNumber, #tested "pen_setPenHueToNumber" : pen.visitSetPenHueToNumber, #tested + + opcodes.MUSIC_PLAY_DRUM_FOR_BEATS: music.visitPlayDrumForBeats, + opcodes.MUSIC_MENU_DRUM: music.visitDrumMenu, } diff --git a/src/scratchtocatrobat/scratch/scratch3visitor/music.py b/src/scratchtocatrobat/scratch/scratch3visitor/music.py new file mode 100644 index 00000000..be757164 --- /dev/null +++ b/src/scratchtocatrobat/scratch/scratch3visitor/music.py @@ -0,0 +1,19 @@ +from visitorUtil import visitGeneric +from scratchtocatrobat.tools import logger + +log = logger.log + +def visitPlayDrumForBeats(blockcontext): + drum = visitGeneric(blockcontext, 'DRUM') + beats = visitGeneric(blockcontext, "BEATS") + return ['drum:duration:elapsed:from:', drum, beats] + +def visitDrumMenu(blockcontext): + block = blockcontext.block + return block.fields["DRUM"][0] + + + + + + diff --git a/src/scratchtocatrobat/scratch/scratch3visitor/scratch2_json_format.py b/src/scratchtocatrobat/scratch/scratch3visitor/scratch2_json_format.py index 1b873e61..13778581 100644 --- a/src/scratchtocatrobat/scratch/scratch3visitor/scratch2_json_format.py +++ b/src/scratchtocatrobat/scratch/scratch3visitor/scratch2_json_format.py @@ -169,6 +169,10 @@ class Scratch3_2Opcodes(object): OPERATOR_OR = "operator_or" OPERATOR_LENGTH = "operator_length" + # music # + MUSIC_PLAY_DRUM_FOR_BEATS = "music_playDrumForBeats" + MUSIC_MENU_DRUM = "music_menu_DRUM" + # not supported block # NOT_SUPPORTED = "not_supported_block" @@ -324,6 +328,10 @@ class Scratch3_2Opcodes(object): OPERATOR_OR: "|", OPERATOR_LENGTH: "stringLength:", + # music # + MUSIC_PLAY_DRUM_FOR_BEATS: "drum:duration:elapsed:from:", + + ### not suported block ### NOT_SUPPORTED: "note:", } diff --git a/src/scratchtocatrobat/scratch/scratch3visitor/sound.py b/src/scratchtocatrobat/scratch/scratch3visitor/sound.py index 8781d42a..5cbfb62b 100644 --- a/src/scratchtocatrobat/scratch/scratch3visitor/sound.py +++ b/src/scratchtocatrobat/scratch/scratch3visitor/sound.py @@ -50,5 +50,3 @@ def visitSounds_menu(blockcontext): block = blockcontext.block return block.fields["SOUND_MENU"][0] - -#TODO: replace music extension bricks with default ones? \ No newline at end of file