Skip to content

Commit dbaddc1

Browse files
authored
Merge pull request Catrobat#3710 from mstoeg/CATROID-304
CATROID-304 Insert UserDefinedBricks into script
2 parents fa1188b + fb83873 commit dbaddc1

23 files changed

+519
-227
lines changed

catroid/src/androidTest/java/org/catrobat/catroid/test/content/bricks/BrickFormulaDefaultValueTest.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@ public void testBrickCategory() {
267267
}
268268
assertNotNull(brickInAdapter);
269269

270-
Brick.BrickField brickField = ((FormulaBrick) brickInAdapter).brickFieldToTextViewIdMap.inverse().get(formulaTextFieldId);
270+
Brick.FormulaField brickField = ((FormulaBrick) brickInAdapter).brickFieldToTextViewIdMap.inverse().get(formulaTextFieldId);
271271
String actual = ((FormulaBrick) brickInAdapter).getFormulaWithBrickField(brickField).getTrimmedFormulaString(ApplicationProvider.getApplicationContext());
272272
assertEquals(expected, actual);
273273
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
/*
2+
* Catroid: An on-device visual programming system for Android devices
3+
* Copyright (C) 2010-2020 The Catrobat Team
4+
* (<http://developer.catrobat.org/credits>)
5+
*
6+
* This program is free software: you can redistribute it and/or modify
7+
* it under the terms of the GNU Affero General Public License as
8+
* published by the Free Software Foundation, either version 3 of the
9+
* License, or (at your option) any later version.
10+
*
11+
* An additional term exception under section 7 of the GNU Affero
12+
* General Public License, version 3, is available at
13+
* http://developer.catrobat.org/license_additional_term
14+
*
15+
* This program is distributed in the hope that it will be useful,
16+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
17+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18+
* GNU Affero General Public License for more details.
19+
*
20+
* You should have received a copy of the GNU Affero General Public License
21+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
22+
*/
23+
24+
package org.catrobat.catroid.uiespresso.formulaeditor;
25+
26+
import org.catrobat.catroid.content.Script;
27+
import org.catrobat.catroid.content.bricks.Brick;
28+
import org.catrobat.catroid.content.bricks.UserDefinedBrick;
29+
import org.catrobat.catroid.formulaeditor.Formula;
30+
import org.catrobat.catroid.test.utils.TestUtils;
31+
import org.catrobat.catroid.ui.SpriteActivity;
32+
import org.catrobat.catroid.uiespresso.content.brick.utils.BrickTestUtils;
33+
import org.catrobat.catroid.uiespresso.util.rules.FragmentActivityTestRule;
34+
import org.catrobat.catroid.userbrick.UserDefinedBrickInput;
35+
import org.catrobat.catroid.userbrick.UserDefinedBrickLabel;
36+
import org.junit.After;
37+
import org.junit.Before;
38+
import org.junit.Rule;
39+
import org.junit.Test;
40+
import org.junit.runner.RunWith;
41+
42+
import androidx.test.core.app.ApplicationProvider;
43+
import androidx.test.ext.junit.runners.AndroidJUnit4;
44+
45+
import static junit.framework.TestCase.assertEquals;
46+
47+
import static org.catrobat.catroid.uiespresso.formulaeditor.utils.FormulaEditorWrapper.onFormulaEditor;
48+
49+
import static java.util.Arrays.asList;
50+
51+
@RunWith(AndroidJUnit4.class)
52+
public class FormulaEditorUserDefinedBrickTest {
53+
54+
private UserDefinedBrick userDefinedBrick;
55+
private static UserDefinedBrickLabel label = new UserDefinedBrickLabel("Label");
56+
private static UserDefinedBrickInput input = new UserDefinedBrickInput("Input");
57+
private static UserDefinedBrickInput secondInput = new UserDefinedBrickInput("SecondInput");
58+
59+
@Rule
60+
public FragmentActivityTestRule<SpriteActivity> baseActivityTestRule = new
61+
FragmentActivityTestRule<>(SpriteActivity.class, SpriteActivity.EXTRA_FRAGMENT_POSITION,
62+
SpriteActivity.FRAGMENT_SCRIPTS);
63+
64+
@After
65+
public void tearDown() throws Exception {
66+
TestUtils.deleteProjects(FormulaEditorUserDefinedBrickTest.class.getSimpleName());
67+
}
68+
69+
@Before
70+
public void setUp() throws Exception {
71+
createProject();
72+
baseActivityTestRule.launchActivity();
73+
}
74+
75+
@Test
76+
public void testChangeFormula() throws Throwable {
77+
clickOnFormulaField(input.getInputFormulaField());
78+
onFormulaEditor().performEnterFormula("1234").performCloseAndSave();
79+
assertEquals("200 ", getValueOfFormulaField(secondInput.getInputFormulaField()));
80+
assertEquals("1234 ", getValueOfFormulaField(input.getInputFormulaField()));
81+
}
82+
83+
@Test
84+
public void testSwitchBetweenFormulaFields() throws Throwable {
85+
clickOnFormulaField(input.getInputFormulaField());
86+
onFormulaEditor()
87+
.checkShows(userDefinedBrick.getFormulaWithBrickField(input.getInputFormulaField())
88+
.getTrimmedFormulaString(ApplicationProvider.getApplicationContext()));
89+
clickOnFormulaField(secondInput.getInputFormulaField());
90+
onFormulaEditor()
91+
.checkShows(userDefinedBrick.getFormulaWithBrickField(secondInput.getInputFormulaField())
92+
.getTrimmedFormulaString(ApplicationProvider.getApplicationContext()));
93+
}
94+
95+
private void createProject() {
96+
Script script = BrickTestUtils.createProjectAndGetStartScript(FormulaEditorUserDefinedBrickTest.class.getSimpleName());
97+
userDefinedBrick = new UserDefinedBrick(asList(input, label, secondInput));
98+
userDefinedBrick.setCallingBrick(true);
99+
userDefinedBrick.getFormulaMap().putIfAbsent(input.getInputFormulaField(), new Formula(100));
100+
userDefinedBrick.getFormulaMap().putIfAbsent(secondInput.getInputFormulaField(), new Formula(200));
101+
script.addBrick(userDefinedBrick);
102+
}
103+
104+
private void clickOnFormulaField(Brick.FormulaField formulaField) throws Throwable {
105+
baseActivityTestRule.runOnUiThread(() -> userDefinedBrick.getTextView(formulaField).callOnClick());
106+
}
107+
108+
private String getValueOfFormulaField(Brick.FormulaField formulaField) {
109+
return userDefinedBrick.getFormulaWithBrickField(formulaField).getTrimmedFormulaString(baseActivityTestRule.getActivity());
110+
}
111+
}

catroid/src/main/java/org/catrobat/catroid/content/bricks/Brick.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,9 @@
4040

4141
public interface Brick extends Serializable, Cloneable {
4242

43-
enum BrickField {
43+
interface FormulaField extends Serializable{ }
44+
45+
enum BrickField implements FormulaField {
4446
COLOR, COLOR_CHANGE, BRIGHTNESS, BRIGHTNESS_CHANGE, X_POSITION, Y_POSITION, X_POSITION_CHANGE, Y_POSITION_CHANGE,
4547
TRANSPARENCY, TRANSPARENCY_CHANGE, SIZE, SIZE_CHANGE, VOLUME, VOLUME_CHANGE, X_DESTINATION, Y_DESTINATION, STEPS,
4648
DURATION_IN_SECONDS, DEGREES, TURN_RIGHT_DEGREES, TURN_LEFT_DEGREES, TIME_TO_WAIT_IN_SECONDS, VARIABLE,

catroid/src/main/java/org/catrobat/catroid/content/bricks/ConcurrentFormulaHashMap.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,14 @@
2626

2727
import java.util.concurrent.ConcurrentHashMap;
2828

29-
public class ConcurrentFormulaHashMap extends ConcurrentHashMap<Brick.BrickField, Formula> implements Cloneable {
29+
public class ConcurrentFormulaHashMap extends ConcurrentHashMap<Brick.FormulaField, Formula> implements Cloneable {
3030

3131
private static final long serialVersionUID = 9030965461744658052L;
3232

3333
@Override
3434
public ConcurrentFormulaHashMap clone() throws CloneNotSupportedException {
3535
ConcurrentFormulaHashMap copiedMap = new ConcurrentFormulaHashMap();
36-
for (Brick.BrickField key : keySet()) {
36+
for (Brick.FormulaField key : keySet()) {
3737
Formula value = get(key);
3838
if (value != null) {
3939
copiedMap.putIfAbsent(key, value.clone());

catroid/src/main/java/org/catrobat/catroid/content/bricks/FormulaBrick.java

+34-34
Original file line numberDiff line numberDiff line change
@@ -53,29 +53,29 @@ public abstract class FormulaBrick extends BrickBaseType implements View.OnClick
5353
@XStreamAlias("formulaList")
5454
ConcurrentFormulaHashMap formulaMap = new ConcurrentFormulaHashMap();
5555

56-
public transient BiMap<BrickField, Integer> brickFieldToTextViewIdMap = HashBiMap.create(2);
56+
public transient BiMap<FormulaField, Integer> brickFieldToTextViewIdMap = HashBiMap.create(2);
5757

58-
public Formula getFormulaWithBrickField(BrickField brickField) throws IllegalArgumentException {
59-
if (formulaMap.containsKey(brickField)) {
60-
return formulaMap.get(brickField);
58+
public Formula getFormulaWithBrickField(FormulaField formulaField) throws IllegalArgumentException {
59+
if (formulaMap.containsKey(formulaField)) {
60+
return formulaMap.get(formulaField);
6161
} else {
6262
throw new IllegalArgumentException("Incompatible Brick Field: " + this.getClass().getSimpleName()
63-
+ " does have BrickField." + brickField.toString());
63+
+ " does not have BrickField." + formulaField.toString());
6464
}
6565
}
6666

67-
public void setFormulaWithBrickField(BrickField brickField, Formula formula) throws IllegalArgumentException {
68-
if (formulaMap.containsKey(brickField)) {
69-
formulaMap.replace(brickField, formula);
67+
public void setFormulaWithBrickField(FormulaField formulaField, Formula formula) throws IllegalArgumentException {
68+
if (formulaMap.containsKey(formulaField)) {
69+
formulaMap.replace(formulaField, formula);
7070
} else {
7171
throw new IllegalArgumentException("Incompatible Brick Field: Cannot set BrickField."
72-
+ brickField.toString() + " fot " + this.getClass().getSimpleName());
72+
+ formulaField.toString() + " for " + this.getClass().getSimpleName());
7373
}
7474
}
7575

76-
protected void addAllowedBrickField(BrickField brickField, int textViewResourceId) {
77-
formulaMap.putIfAbsent(brickField, new Formula(0));
78-
brickFieldToTextViewIdMap.put(brickField, textViewResourceId);
76+
protected void addAllowedBrickField(FormulaField formulaField, int textViewResourceId) {
77+
formulaMap.putIfAbsent(formulaField, new Formula(0));
78+
brickFieldToTextViewIdMap.put(formulaField, textViewResourceId);
7979
}
8080

8181
@Override
@@ -86,11 +86,11 @@ public void addRequiredResources(final ResourcesSet requiredResourcesSet) {
8686
}
8787
}
8888

89-
public void replaceFormulaBrickField(BrickField oldBrickField, BrickField newBrickField) {
90-
if (formulaMap.containsKey(oldBrickField)) {
91-
Formula brickFormula = formulaMap.get(oldBrickField);
92-
formulaMap.remove(oldBrickField);
93-
formulaMap.put(newBrickField, brickFormula);
89+
public void replaceFormulaBrickField(FormulaField oldFormulaField, FormulaField newFormulaField) {
90+
if (formulaMap.containsKey(oldFormulaField)) {
91+
Formula brickFormula = formulaMap.get(oldFormulaField);
92+
formulaMap.remove(oldFormulaField);
93+
formulaMap.put(newFormulaField, brickFormula);
9494
}
9595
}
9696

@@ -104,17 +104,17 @@ public Brick clone() throws CloneNotSupportedException {
104104
@Override
105105
public View getView(Context context) {
106106
super.getView(context);
107-
for (BiMap.Entry<BrickField, Integer> entry : brickFieldToTextViewIdMap.entrySet()) {
108-
TextView brickFieldView = view.findViewById(entry.getValue());
109-
brickFieldView.setText(getFormulaWithBrickField(entry.getKey()).getTrimmedFormulaString(context));
107+
for (BiMap.Entry<FormulaField, Integer> entry : brickFieldToTextViewIdMap.entrySet()) {
108+
TextView formulaFieldView = view.findViewById(entry.getValue());
109+
formulaFieldView.setText(getFormulaWithBrickField(entry.getKey()).getTrimmedFormulaString(context));
110110
}
111111
return view;
112112
}
113113

114114
public void setClickListeners() {
115-
for (BiMap.Entry<BrickField, Integer> entry : brickFieldToTextViewIdMap.entrySet()) {
116-
TextView brickFieldView = view.findViewById(entry.getValue());
117-
brickFieldView.setOnClickListener(this);
115+
for (BiMap.Entry<FormulaField, Integer> entry : brickFieldToTextViewIdMap.entrySet()) {
116+
TextView formulaFieldView = view.findViewById(entry.getValue());
117+
formulaFieldView.setOnClickListener(this);
118118
}
119119
}
120120

@@ -127,12 +127,12 @@ public ConcurrentFormulaHashMap getFormulaMap() {
127127
return formulaMap;
128128
}
129129

130-
public TextView getTextView(BrickField brickField) {
131-
return view.findViewById(brickFieldToTextViewIdMap.get(brickField));
130+
public TextView getTextView(FormulaField formulaField) {
131+
return view.findViewById(brickFieldToTextViewIdMap.get(formulaField));
132132
}
133133

134-
public void highlightTextView(BrickField brickField) {
135-
TextView formulaTextField = view.findViewById(brickFieldToTextViewIdMap.get(brickField));
134+
public void highlightTextView(FormulaField formulaField) {
135+
TextView formulaTextField = getTextView(formulaField);
136136

137137
formulaTextField.getBackground().mutate()
138138
.setColorFilter(view.getContext().getResources()
@@ -152,30 +152,30 @@ public void showFormulaEditorToEditFormula(View view) {
152152
}
153153
}
154154

155-
public BrickField getDefaultBrickField() {
155+
public FormulaField getDefaultBrickField() {
156156
return formulaMap.keys().nextElement();
157157
}
158158

159-
boolean isBrickFieldANumber(BrickField brickField) {
160-
return getFormulaWithBrickField(brickField).isNumber();
159+
boolean isBrickFieldANumber(FormulaField formulaField) {
160+
return getFormulaWithBrickField(formulaField).isNumber();
161161
}
162162

163163
public View getCustomView(Context context) {
164164
throw new IllegalStateException("There is no custom view for the " + getClass().getSimpleName() + ".");
165165
}
166166

167-
public Brick.BrickField getBrickFieldFromTextViewId(int textViewId) {
167+
public FormulaField getBrickFieldFromTextViewId(int textViewId) {
168168
return brickFieldToTextViewIdMap.inverse().get(textViewId);
169169
}
170170

171-
protected void setSecondsLabel(View view, BrickField brickField) {
171+
protected void setSecondsLabel(View view, FormulaField formulaField) {
172172
TextView textView = view.findViewById(R.id.brick_seconds_label);
173173
Context context = textView.getContext();
174174

175-
if (getFormulaWithBrickField(brickField).isNumber()) {
175+
if (getFormulaWithBrickField(formulaField).isNumber()) {
176176
try {
177177
Sprite sprite = ProjectManager.getInstance().getCurrentSprite();
178-
Double formulaValue = formulaMap.get(brickField).interpretDouble(sprite);
178+
Double formulaValue = formulaMap.get(formulaField).interpretDouble(sprite);
179179
textView.setText(context.getResources().getQuantityString(R.plurals.second_plural,
180180
Utils.convertDoubleToPluralInteger(formulaValue)));
181181
return;

0 commit comments

Comments
 (0)