From 15b89ff164688cdcd8a171c8b51555554055fb4b Mon Sep 17 00:00:00 2001 From: tobi Date: Mon, 23 Aug 2021 15:22:42 +0200 Subject: [PATCH 1/5] STCC-276 Convert Play drum X for Y beats [TN] --- src/scratchtocatrobat/converter/converter.py | 23 +++++++++++++++++++ .../converter/test_converter.py | 14 +++++++++++ .../scratch/scratch3visitor/blockmapping.py | 9 ++++++-- .../scratch/scratch3visitor/music.py | 19 +++++++++++++++ .../scratch3visitor/scratch2_json_format.py | 9 ++++++++ .../scratch/scratch3visitor/sound.py | 2 -- 6 files changed, 72 insertions(+), 4 deletions(-) create mode 100644 src/scratchtocatrobat/scratch/scratch3visitor/music.py 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..b3146160 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 @@ -125,7 +127,7 @@ "operator_equals" : operator.visitEquals,#tested "operator_mathop" : operator.visitMathop,#tested "operator_and" : operator.visitAnd,#tested - "operator_round" : operator.visitRound,#tested + "operator_round" : operator.visitRound,#testedUSIC_PLAY_DRUM_FOR_BEATS "operator_multiply" : operator.visitMultiply,#tested "operator_random" : operator.visitRandom,#tested "operator_divide" : operator.visitDivide,#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..2362ff49 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:", } @@ -359,6 +367,7 @@ class MenuTypes(object): TOUCHING_OBJECT = "TOUCHINGOBJECTMENU" OBJECT = "OBJECT" COLOR_PARAM = "colorParam" + COLOR_PARAM = "colorParam" class InputTypes(object): 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 From 4bf8e3868f992b95431a819335582dc4ebadc8b2 Mon Sep 17 00:00:00 2001 From: tobi Date: Mon, 23 Aug 2021 16:33:16 +0200 Subject: [PATCH 2/5] STCC-275 Convert Play note X for Y beats [TN] --- src/scratchtocatrobat/converter/converter.py | 8 ++++++++ .../converter/test_converter.py | 18 ++++++++++++++++++ .../scratch/scratch3visitor/blockmapping.py | 2 ++ .../scratch/scratch3visitor/music.py | 10 ++++++++++ .../scratch3visitor/scratch2_json_format.py | 3 +++ 5 files changed, 41 insertions(+) diff --git a/src/scratchtocatrobat/converter/converter.py b/src/scratchtocatrobat/converter/converter.py index ee77ece9..0b403650 100644 --- a/src/scratchtocatrobat/converter/converter.py +++ b/src/scratchtocatrobat/converter/converter.py @@ -441,6 +441,7 @@ class _ScratchToCatrobat(object): # music "drum:duration:elapsed:from:": catbricks.PlayDrumForBeatsBrick, + "noteOn:duration:elapsed:from:": catbricks.PlayNoteForBeatsBrick, # bubble bricks "say:duration:elapsed:from:": catbricks.SayForBubbleBrick, @@ -3459,3 +3460,10 @@ def _convert_play_drum_for_beats_block(self): play_drum_brick.drumSelection = drum_selection return play_drum_brick + + @_register_handler(_block_name_to_handler_map, "noteOn:duration:elapsed:from:") + def _convert_play_note_for_beats_block(self): + [note, duration] = self.arguments + + play_note_brick = self.CatrobatClass(catformula.Formula(note), catformula.Formula(duration)) + return play_note_brick diff --git a/src/scratchtocatrobat/converter/test_converter.py b/src/scratchtocatrobat/converter/test_converter.py index 55a9b391..72a37501 100644 --- a/src/scratchtocatrobat/converter/test_converter.py +++ b/src/scratchtocatrobat/converter/test_converter.py @@ -1425,11 +1425,29 @@ def test_can_convert_play_drum_for_beats_block(self): 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 + # noteOn:duration:elapsed:from: + def test_can_convert_play_note_for_beats_block(self): + note = 60.0 + beats = 1.0 + scratch_block = ["noteOn:duration:elapsed:from:", note, beats] + [catr_brick] = self.block_converter._catrobat_bricks_from(scratch_block, DUMMY_CATR_SPRITE) + assert isinstance(catr_brick, catbricks.PlayNoteForBeatsBrick) + + formula_tree_list_delete_item = catr_brick.getFormulaWithBrickField(catbasebrick.BrickField.NOTE_TO_PLAY).formulaTree # @UndefinedVariable + assert formula_tree_list_delete_item.type == catformula.FormulaElement.ElementType.NUMBER + assert formula_tree_list_delete_item.value == str(note) + + formula_tree_list_delete_item = catr_brick.getFormulaWithBrickField(catbasebrick.BrickField.BEATS_TO_PLAY_NOTE).formulaTree # @UndefinedVariable + assert formula_tree_list_delete_item.type == catformula.FormulaElement.ElementType.NUMBER + assert formula_tree_list_delete_item.value == str(beats) + + # deleteLine:ofList: def test_can_convert_delete_line_from_list_by_index_block(self): index = 2 diff --git a/src/scratchtocatrobat/scratch/scratch3visitor/blockmapping.py b/src/scratchtocatrobat/scratch/scratch3visitor/blockmapping.py index b3146160..96298ee5 100644 --- a/src/scratchtocatrobat/scratch/scratch3visitor/blockmapping.py +++ b/src/scratchtocatrobat/scratch/scratch3visitor/blockmapping.py @@ -172,5 +172,7 @@ opcodes.MUSIC_PLAY_DRUM_FOR_BEATS: music.visitPlayDrumForBeats, opcodes.MUSIC_MENU_DRUM: music.visitDrumMenu, + opcodes.MUSIC_PLAY_NOTE_FOR_BEATS: music.visitPlayNoteForBeats, + opcodes.NOTE: music.visitNoteMenu, } diff --git a/src/scratchtocatrobat/scratch/scratch3visitor/music.py b/src/scratchtocatrobat/scratch/scratch3visitor/music.py index be757164..aef5f079 100644 --- a/src/scratchtocatrobat/scratch/scratch3visitor/music.py +++ b/src/scratchtocatrobat/scratch/scratch3visitor/music.py @@ -12,6 +12,16 @@ def visitDrumMenu(blockcontext): block = blockcontext.block return block.fields["DRUM"][0] +def visitPlayNoteForBeats(blockcontext): + note = visitGeneric(blockcontext, 'NOTE') + beats = visitGeneric(blockcontext, "BEATS") + return ['noteOn:duration:elapsed:from:', note, beats] + +def visitNoteMenu(blockcontext): + block = blockcontext.block + return block.fields["NOTE"][0] + + diff --git a/src/scratchtocatrobat/scratch/scratch3visitor/scratch2_json_format.py b/src/scratchtocatrobat/scratch/scratch3visitor/scratch2_json_format.py index 2362ff49..f29e5389 100644 --- a/src/scratchtocatrobat/scratch/scratch3visitor/scratch2_json_format.py +++ b/src/scratchtocatrobat/scratch/scratch3visitor/scratch2_json_format.py @@ -172,6 +172,8 @@ class Scratch3_2Opcodes(object): # music # MUSIC_PLAY_DRUM_FOR_BEATS = "music_playDrumForBeats" MUSIC_MENU_DRUM = "music_menu_DRUM" + MUSIC_PLAY_NOTE_FOR_BEATS = "music_playNoteForBeats" + NOTE = "note" # not supported block # NOT_SUPPORTED = "not_supported_block" @@ -330,6 +332,7 @@ class Scratch3_2Opcodes(object): # music # MUSIC_PLAY_DRUM_FOR_BEATS: "drum:duration:elapsed:from:", + MUSIC_PLAY_NOTE_FOR_BEATS: "noteOn:duration:elapsed:from:", ### not suported block ### From 699778fc628b9c0c6b8a481395d8532edb9baec2 Mon Sep 17 00:00:00 2001 From: tobi Date: Mon, 23 Aug 2021 17:30:42 +0200 Subject: [PATCH 3/5] STCC-274 Convert Change tempo by X [TN] --- src/scratchtocatrobat/converter/converter.py | 8 ++++++++ src/scratchtocatrobat/converter/test_converter.py | 10 ++++++++++ .../scratch/scratch3visitor/blockmapping.py | 4 +++- src/scratchtocatrobat/scratch/scratch3visitor/music.py | 6 ++++++ .../scratch/scratch3visitor/scratch2_json_format.py | 3 ++- 5 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/scratchtocatrobat/converter/converter.py b/src/scratchtocatrobat/converter/converter.py index 0b403650..998a854b 100644 --- a/src/scratchtocatrobat/converter/converter.py +++ b/src/scratchtocatrobat/converter/converter.py @@ -442,6 +442,7 @@ class _ScratchToCatrobat(object): # music "drum:duration:elapsed:from:": catbricks.PlayDrumForBeatsBrick, "noteOn:duration:elapsed:from:": catbricks.PlayNoteForBeatsBrick, + "changeTempoBy:": catbricks.ChangeTempoByNBrick, # bubble bricks "say:duration:elapsed:from:": catbricks.SayForBubbleBrick, @@ -3467,3 +3468,10 @@ def _convert_play_note_for_beats_block(self): play_note_brick = self.CatrobatClass(catformula.Formula(note), catformula.Formula(duration)) return play_note_brick + + @_register_handler(_block_name_to_handler_map, "changeTempoBy:") + def _convert_change_tempo_by_block(self): + [tempo] = self.arguments + + change_tempo_brick = self.CatrobatClass(catformula.Formula(tempo)) + return change_tempo_brick diff --git a/src/scratchtocatrobat/converter/test_converter.py b/src/scratchtocatrobat/converter/test_converter.py index 72a37501..557df7ea 100644 --- a/src/scratchtocatrobat/converter/test_converter.py +++ b/src/scratchtocatrobat/converter/test_converter.py @@ -1447,6 +1447,16 @@ def test_can_convert_play_note_for_beats_block(self): assert formula_tree_list_delete_item.type == catformula.FormulaElement.ElementType.NUMBER assert formula_tree_list_delete_item.value == str(beats) + # changeTempoBy: + def test_can_convert_change_tempo_by_block(self): + tempo = 20.0 + scratch_block = ["changeTempoBy:", tempo] + [catr_brick] = self.block_converter._catrobat_bricks_from(scratch_block, DUMMY_CATR_SPRITE) + assert isinstance(catr_brick, catbricks.ChangeTempoByNBrick) + + formula_tree_list_delete_item = catr_brick.getFormulaWithBrickField(catbasebrick.BrickField.TEMPO_CHANGE).formulaTree # @UndefinedVariable + assert formula_tree_list_delete_item.type == catformula.FormulaElement.ElementType.NUMBER + assert formula_tree_list_delete_item.value == str(tempo) # deleteLine:ofList: def test_can_convert_delete_line_from_list_by_index_block(self): diff --git a/src/scratchtocatrobat/scratch/scratch3visitor/blockmapping.py b/src/scratchtocatrobat/scratch/scratch3visitor/blockmapping.py index 96298ee5..b9239d0c 100644 --- a/src/scratchtocatrobat/scratch/scratch3visitor/blockmapping.py +++ b/src/scratchtocatrobat/scratch/scratch3visitor/blockmapping.py @@ -127,7 +127,7 @@ "operator_equals" : operator.visitEquals,#tested "operator_mathop" : operator.visitMathop,#tested "operator_and" : operator.visitAnd,#tested - "operator_round" : operator.visitRound,#testedUSIC_PLAY_DRUM_FOR_BEATS + "operator_round" : operator.visitRound,#tested "operator_multiply" : operator.visitMultiply,#tested "operator_random" : operator.visitRandom,#tested "operator_divide" : operator.visitDivide,#tested @@ -174,5 +174,7 @@ opcodes.MUSIC_MENU_DRUM: music.visitDrumMenu, opcodes.MUSIC_PLAY_NOTE_FOR_BEATS: music.visitPlayNoteForBeats, opcodes.NOTE: music.visitNoteMenu, + opcodes.MUSIC_CHANGE_TEMPO: music.visitChangeTempoBy, + } diff --git a/src/scratchtocatrobat/scratch/scratch3visitor/music.py b/src/scratchtocatrobat/scratch/scratch3visitor/music.py index aef5f079..7b26ab08 100644 --- a/src/scratchtocatrobat/scratch/scratch3visitor/music.py +++ b/src/scratchtocatrobat/scratch/scratch3visitor/music.py @@ -21,6 +21,12 @@ def visitNoteMenu(blockcontext): block = blockcontext.block return block.fields["NOTE"][0] +def visitChangeTempoBy(blockcontext): + tempo = visitGeneric(blockcontext, 'TEMPO') + return ['changeTempoBy:', tempo] + + + diff --git a/src/scratchtocatrobat/scratch/scratch3visitor/scratch2_json_format.py b/src/scratchtocatrobat/scratch/scratch3visitor/scratch2_json_format.py index f29e5389..3d528486 100644 --- a/src/scratchtocatrobat/scratch/scratch3visitor/scratch2_json_format.py +++ b/src/scratchtocatrobat/scratch/scratch3visitor/scratch2_json_format.py @@ -174,6 +174,7 @@ class Scratch3_2Opcodes(object): MUSIC_MENU_DRUM = "music_menu_DRUM" MUSIC_PLAY_NOTE_FOR_BEATS = "music_playNoteForBeats" NOTE = "note" + MUSIC_CHANGE_TEMPO = "music_changeTempo" # not supported block # NOT_SUPPORTED = "not_supported_block" @@ -333,6 +334,7 @@ class Scratch3_2Opcodes(object): # music # MUSIC_PLAY_DRUM_FOR_BEATS: "drum:duration:elapsed:from:", MUSIC_PLAY_NOTE_FOR_BEATS: "noteOn:duration:elapsed:from:", + MUSIC_CHANGE_TEMPO: "changeTempoBy:", ### not suported block ### @@ -370,7 +372,6 @@ class MenuTypes(object): TOUCHING_OBJECT = "TOUCHINGOBJECTMENU" OBJECT = "OBJECT" COLOR_PARAM = "colorParam" - COLOR_PARAM = "colorParam" class InputTypes(object): From 178891cd3ab66423e05701236fca1756a3598049 Mon Sep 17 00:00:00 2001 From: tobi Date: Mon, 23 Aug 2021 20:26:56 +0200 Subject: [PATCH 4/5] STCC-278 Convert Set tempo to X [TN] --- src/scratchtocatrobat/converter/converter.py | 11 +++++++++++ src/scratchtocatrobat/converter/test_converter.py | 13 +++++++++++-- .../scratch/scratch3visitor/blockmapping.py | 2 +- .../scratch/scratch3visitor/music.py | 3 +++ .../scratch/scratch3visitor/scratch2_json_format.py | 2 ++ 5 files changed, 28 insertions(+), 3 deletions(-) diff --git a/src/scratchtocatrobat/converter/converter.py b/src/scratchtocatrobat/converter/converter.py index 998a854b..a8caa3fb 100644 --- a/src/scratchtocatrobat/converter/converter.py +++ b/src/scratchtocatrobat/converter/converter.py @@ -443,6 +443,7 @@ class _ScratchToCatrobat(object): "drum:duration:elapsed:from:": catbricks.PlayDrumForBeatsBrick, "noteOn:duration:elapsed:from:": catbricks.PlayNoteForBeatsBrick, "changeTempoBy:": catbricks.ChangeTempoByNBrick, + "setTempoTo:": catbricks.SetTempoBrick, # bubble bricks "say:duration:elapsed:from:": catbricks.SayForBubbleBrick, @@ -3475,3 +3476,13 @@ def _convert_change_tempo_by_block(self): change_tempo_brick = self.CatrobatClass(catformula.Formula(tempo)) return change_tempo_brick + + @_register_handler(_block_name_to_handler_map, "setTempoTo:") + def _convert_set_tempo_to_block(self): + [tempo] = self.arguments + + set_tempo_brick = self.CatrobatClass(catformula.Formula(tempo)) + return set_tempo_brick + + + diff --git a/src/scratchtocatrobat/converter/test_converter.py b/src/scratchtocatrobat/converter/test_converter.py index 557df7ea..b1f75b5a 100644 --- a/src/scratchtocatrobat/converter/test_converter.py +++ b/src/scratchtocatrobat/converter/test_converter.py @@ -1458,6 +1458,17 @@ def test_can_convert_change_tempo_by_block(self): assert formula_tree_list_delete_item.type == catformula.FormulaElement.ElementType.NUMBER assert formula_tree_list_delete_item.value == str(tempo) + # setTempoTo: + def test_can_convert_set_tempo_to_block(self): + tempo = 20.0 + scratch_block = ["setTempoTo:", tempo] + [catr_brick] = self.block_converter._catrobat_bricks_from(scratch_block, DUMMY_CATR_SPRITE) + assert isinstance(catr_brick, catbricks.SetTempoBrick) + + formula_tree_list_delete_item = catr_brick.getFormulaWithBrickField(catbasebrick.BrickField.TEMPO).formulaTree # @UndefinedVariable + assert formula_tree_list_delete_item.type == catformula.FormulaElement.ElementType.NUMBER + assert formula_tree_list_delete_item.value == str(tempo) + # deleteLine:ofList: def test_can_convert_delete_line_from_list_by_index_block(self): index = 2 @@ -1468,7 +1479,6 @@ 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] @@ -1513,7 +1523,6 @@ def test_can_convert_delete_all_lines_from_list_block(self): assert formula_tree_list_delete_item.leftChild == None assert formula_tree_list_delete_item.rightChild == None - # setLine:ofList:to: def test_can_convert_set_line_via_str_index_of_list_to_block(self): index, value = "2", "1" diff --git a/src/scratchtocatrobat/scratch/scratch3visitor/blockmapping.py b/src/scratchtocatrobat/scratch/scratch3visitor/blockmapping.py index b9239d0c..2c915be7 100644 --- a/src/scratchtocatrobat/scratch/scratch3visitor/blockmapping.py +++ b/src/scratchtocatrobat/scratch/scratch3visitor/blockmapping.py @@ -175,6 +175,6 @@ opcodes.MUSIC_PLAY_NOTE_FOR_BEATS: music.visitPlayNoteForBeats, opcodes.NOTE: music.visitNoteMenu, opcodes.MUSIC_CHANGE_TEMPO: music.visitChangeTempoBy, - + opcodes.MUSIC_SET_TEMPO: music.visitSetTempoTo, } diff --git a/src/scratchtocatrobat/scratch/scratch3visitor/music.py b/src/scratchtocatrobat/scratch/scratch3visitor/music.py index 7b26ab08..61f15e3e 100644 --- a/src/scratchtocatrobat/scratch/scratch3visitor/music.py +++ b/src/scratchtocatrobat/scratch/scratch3visitor/music.py @@ -25,6 +25,9 @@ def visitChangeTempoBy(blockcontext): tempo = visitGeneric(blockcontext, 'TEMPO') return ['changeTempoBy:', tempo] +def visitSetTempoTo(blockcontext): + tempo = visitGeneric(blockcontext, 'TEMPO') + return ['setTempoTo:', tempo] diff --git a/src/scratchtocatrobat/scratch/scratch3visitor/scratch2_json_format.py b/src/scratchtocatrobat/scratch/scratch3visitor/scratch2_json_format.py index 3d528486..08d3e221 100644 --- a/src/scratchtocatrobat/scratch/scratch3visitor/scratch2_json_format.py +++ b/src/scratchtocatrobat/scratch/scratch3visitor/scratch2_json_format.py @@ -175,6 +175,7 @@ class Scratch3_2Opcodes(object): MUSIC_PLAY_NOTE_FOR_BEATS = "music_playNoteForBeats" NOTE = "note" MUSIC_CHANGE_TEMPO = "music_changeTempo" + MUSIC_SET_TEMPO = "music_setTempo" # not supported block # NOT_SUPPORTED = "not_supported_block" @@ -335,6 +336,7 @@ class Scratch3_2Opcodes(object): MUSIC_PLAY_DRUM_FOR_BEATS: "drum:duration:elapsed:from:", MUSIC_PLAY_NOTE_FOR_BEATS: "noteOn:duration:elapsed:from:", MUSIC_CHANGE_TEMPO: "changeTempoBy:", + MUSIC_SET_TEMPO: "setTempoTo:", ### not suported block ### From a6ca954035091a2c8e493c4bf1aace8ffefcbc5e Mon Sep 17 00:00:00 2001 From: tobi Date: Tue, 5 Oct 2021 15:54:16 +0200 Subject: [PATCH 5/5] STCC-227 Convert Pause X beats [TN] --- src/scratchtocatrobat/converter/converter.py | 7 +++++++ src/scratchtocatrobat/converter/test_converter.py | 10 ++++++++++ .../scratch/scratch3visitor/blockmapping.py | 1 + src/scratchtocatrobat/scratch/scratch3visitor/music.py | 3 +++ .../scratch/scratch3visitor/scratch2_json_format.py | 2 ++ 5 files changed, 23 insertions(+) diff --git a/src/scratchtocatrobat/converter/converter.py b/src/scratchtocatrobat/converter/converter.py index a8caa3fb..c8473c98 100644 --- a/src/scratchtocatrobat/converter/converter.py +++ b/src/scratchtocatrobat/converter/converter.py @@ -444,6 +444,7 @@ class _ScratchToCatrobat(object): "noteOn:duration:elapsed:from:": catbricks.PlayNoteForBeatsBrick, "changeTempoBy:": catbricks.ChangeTempoByNBrick, "setTempoTo:": catbricks.SetTempoBrick, + "rest:elapsed:from:": catbricks.PauseForBeatsBrick, # bubble bricks "say:duration:elapsed:from:": catbricks.SayForBubbleBrick, @@ -3484,5 +3485,11 @@ def _convert_set_tempo_to_block(self): set_tempo_brick = self.CatrobatClass(catformula.Formula(tempo)) return set_tempo_brick + @_register_handler(_block_name_to_handler_map, "rest:elapsed:from:") + def _convert_rest_for_beats_block(self): + [beats] = self.arguments + + rest_for_beats = self.CatrobatClass(catformula.Formula(beats)) + return rest_for_beats diff --git a/src/scratchtocatrobat/converter/test_converter.py b/src/scratchtocatrobat/converter/test_converter.py index b1f75b5a..499825ff 100644 --- a/src/scratchtocatrobat/converter/test_converter.py +++ b/src/scratchtocatrobat/converter/test_converter.py @@ -1469,6 +1469,16 @@ def test_can_convert_set_tempo_to_block(self): assert formula_tree_list_delete_item.type == catformula.FormulaElement.ElementType.NUMBER assert formula_tree_list_delete_item.value == str(tempo) + def test_can_convert_rest_for_beats_block(self): + beats = 0.25 + scratch_block = ["rest:elapsed:from:", beats] + [catr_brick] = self.block_converter._catrobat_bricks_from(scratch_block, DUMMY_CATR_SPRITE) + assert isinstance(catr_brick, catbricks.PauseForBeatsBrick) + + formula_tree_list_delete_item = catr_brick.getFormulaWithBrickField(catbasebrick.BrickField.BEATS_TO_PAUSE).formulaTree # @UndefinedVariable + assert formula_tree_list_delete_item.type == catformula.FormulaElement.ElementType.NUMBER + assert formula_tree_list_delete_item.value == str(beats) + # deleteLine:ofList: def test_can_convert_delete_line_from_list_by_index_block(self): index = 2 diff --git a/src/scratchtocatrobat/scratch/scratch3visitor/blockmapping.py b/src/scratchtocatrobat/scratch/scratch3visitor/blockmapping.py index 2c915be7..a84ac474 100644 --- a/src/scratchtocatrobat/scratch/scratch3visitor/blockmapping.py +++ b/src/scratchtocatrobat/scratch/scratch3visitor/blockmapping.py @@ -176,5 +176,6 @@ opcodes.NOTE: music.visitNoteMenu, opcodes.MUSIC_CHANGE_TEMPO: music.visitChangeTempoBy, opcodes.MUSIC_SET_TEMPO: music.visitSetTempoTo, + opcodes.MUSIC_REST_FOR_BEATS: music.visitRestForBeats, } diff --git a/src/scratchtocatrobat/scratch/scratch3visitor/music.py b/src/scratchtocatrobat/scratch/scratch3visitor/music.py index 61f15e3e..f1ba9430 100644 --- a/src/scratchtocatrobat/scratch/scratch3visitor/music.py +++ b/src/scratchtocatrobat/scratch/scratch3visitor/music.py @@ -29,6 +29,9 @@ def visitSetTempoTo(blockcontext): tempo = visitGeneric(blockcontext, 'TEMPO') return ['setTempoTo:', tempo] +def visitRestForBeats(blockcontext): + beats = visitGeneric(blockcontext, "BEATS") + return ['rest:elapsed:from:', beats] diff --git a/src/scratchtocatrobat/scratch/scratch3visitor/scratch2_json_format.py b/src/scratchtocatrobat/scratch/scratch3visitor/scratch2_json_format.py index 08d3e221..203ff206 100644 --- a/src/scratchtocatrobat/scratch/scratch3visitor/scratch2_json_format.py +++ b/src/scratchtocatrobat/scratch/scratch3visitor/scratch2_json_format.py @@ -176,6 +176,7 @@ class Scratch3_2Opcodes(object): NOTE = "note" MUSIC_CHANGE_TEMPO = "music_changeTempo" MUSIC_SET_TEMPO = "music_setTempo" + MUSIC_REST_FOR_BEATS = "music_restForBeats" # not supported block # NOT_SUPPORTED = "not_supported_block" @@ -337,6 +338,7 @@ class Scratch3_2Opcodes(object): MUSIC_PLAY_NOTE_FOR_BEATS: "noteOn:duration:elapsed:from:", MUSIC_CHANGE_TEMPO: "changeTempoBy:", MUSIC_SET_TEMPO: "setTempoTo:", + MUSIC_REST_FOR_BEATS: "rest:elapsed:from:", ### not suported block ###