Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions catroid/src/main/java/org/catrobat/catroid/content/Script.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ public abstract class Script implements Serializable, Cloneable {

protected List<Brick> brickList = new ArrayList<>();
protected boolean commentedOut = false;
private transient boolean collapsed = false;

@XStreamAsAttribute
protected float posX;
Expand All @@ -71,6 +72,7 @@ public Script clone() throws CloneNotSupportedException {
}

clone.commentedOut = commentedOut;
clone.collapsed = false;
clone.scriptBrick = null;
clone.posX = posX;
clone.posY = posY;
Expand Down Expand Up @@ -109,6 +111,14 @@ public void setCommentedOut(boolean commentedOut) {
}
}

public boolean isCollapsed() {
return collapsed;
}

public void setCollapsed(boolean collapsed) {
this.collapsed = collapsed;
}

public void setParents() {
ScriptBrick scriptBrick = getScriptBrick();
scriptBrick.setParent(null);
Expand Down Expand Up @@ -145,8 +155,10 @@ public void addBrick(int position, Brick brick) {

public void addToFlatList(List<Brick> bricks) {
bricks.add(getScriptBrick());
for (Brick brick : brickList) {
brick.addToFlatList(bricks);
if (!collapsed) {
for (Brick brick : brickList) {
brick.addToFlatList(bricks);
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ public abstract class BrickBaseType implements Brick {

protected boolean commentedOut;

protected transient boolean collapsed;

protected UUID brickId = UUID.randomUUID();

@Override
Expand All @@ -66,6 +68,14 @@ public void setCommentedOut(boolean commentedOut) {
this.commentedOut = commentedOut;
}

public boolean isCollapsed() {
return collapsed;
}

public void setCollapsed(boolean collapsed) {
this.collapsed = collapsed;
}

@Nullable
@Override
public CheckBox getCheckBox() {
Expand All @@ -79,6 +89,7 @@ public Brick clone() throws CloneNotSupportedException {
clone.checkbox = null;
clone.parent = null;
clone.commentedOut = commentedOut;
clone.collapsed = false;
clone.brickId = UUID.randomUUID();
return clone;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,7 @@ public void setUndoMenuItemVisibility(boolean isVisible) {
public boolean onPrepareOptionsMenu(Menu menu) {
if (getCurrentFragment() instanceof ScriptFragment) {
menu.findItem(R.id.comment_in_out).setVisible(true);
menu.findItem(R.id.collapse_expand).setVisible(true);
showUndo(isUndoMenuItemVisible);
} else if (getCurrentFragment() instanceof LookListFragment) {
showUndo(isUndoMenuItemVisible);
Expand Down
6 changes: 6 additions & 0 deletions catroid/src/main/java/org/catrobat/catroid/ui/UiUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,12 @@
return R.drawable.ic_library_add_small;
case R.string.menu_rate_us:
return R.drawable.ic_star_rate;
case R.string.brick_context_dialog_collapse_script:

Check warning

Code scanning / Android Lint

Checks use of resource IDs in places requiring constants Warning

Resource IDs will be non-final by default in Android Gradle Plugin version 8.0, avoid using them in switch case statements
case R.string.brick_context_dialog_collapse_brick:

Check warning on line 105 in catroid/src/main/java/org/catrobat/catroid/ui/UiUtils.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Merge the previous cases into this one using comma-separated label.

See more on https://sonarcloud.io/project/issues?id=Catrobat_Catroid&issues=AZ2OwcHnVfXNdCGJpqD4&open=AZ2OwcHnVfXNdCGJpqD4&pullRequest=5196
return R.drawable.ic_collapse;
case R.string.brick_context_dialog_expand_script:

Check warning

Code scanning / Android Lint

Checks use of resource IDs in places requiring constants Warning

Resource IDs will be non-final by default in Android Gradle Plugin version 8.0, avoid using them in switch case statements
case R.string.brick_context_dialog_expand_brick:

Check warning on line 108 in catroid/src/main/java/org/catrobat/catroid/ui/UiUtils.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Merge the previous cases into this one using comma-separated label.

See more on https://sonarcloud.io/project/issues?id=Catrobat_Catroid&issues=AZ2OwcHnVfXNdCGJpqD5&open=AZ2OwcHnVfXNdCGJpqD5&pullRequest=5196
return R.drawable.ic_expand;
default:
return R.drawable.ic_placeholder;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,21 @@
import android.graphics.ColorMatrix
import android.graphics.ColorMatrixColorFilter
import android.graphics.drawable.Drawable
import android.view.Gravity
import android.view.View
import android.view.ViewGroup
import android.widget.AdapterView
import android.widget.AdapterView.OnItemLongClickListener
import android.widget.BaseAdapter
import android.widget.ImageView
import android.widget.LinearLayout

Check warning

Code scanning / detekt

Detects unused imports Warning

Unused import

Check warning

Code scanning / detekt

Unused Imports are dead code and should be removed. Warning

The import 'android.widget.LinearLayout' is unused.
Comment thread
github-advanced-security[bot] marked this conversation as resolved.
Fixed
Comment thread
github-advanced-security[bot] marked this conversation as resolved.
Fixed
import androidx.annotation.IntDef
import androidx.core.content.ContextCompat
import org.catrobat.catroid.R
import org.catrobat.catroid.content.Script
import org.catrobat.catroid.content.Sprite
import org.catrobat.catroid.content.bricks.Brick
import org.catrobat.catroid.content.bricks.BrickBaseType
import org.catrobat.catroid.content.bricks.CompositeBrick
import org.catrobat.catroid.content.bricks.EmptyEventBrick
import org.catrobat.catroid.content.bricks.EndBrick
Expand All @@ -53,7 +59,7 @@
AdapterView.OnItemClickListener,
OnItemLongClickListener {
@kotlin.annotation.Retention(AnnotationRetention.SOURCE)
@IntDef(NONE, ALL, SCRIPTS_ONLY, CONNECTED_ONLY)
@IntDef(NONE, ALL, SCRIPTS_ONLY, CONNECTED_ONLY, COLLAPSE_EXPAND)
internal annotation class CheckBoxMode

@CheckBoxMode
Expand Down Expand Up @@ -81,6 +87,8 @@
const val ALL = 1
const val SCRIPTS_ONLY = 2
const val CONNECTED_ONLY = 3
const val COLLAPSE_EXPAND = 4
private const val COLLAPSE_INDICATOR_TAG = "collapse_indicator"

@JvmStatic
fun colorAsCommentedOut(background: Drawable) {
Expand Down Expand Up @@ -117,9 +125,43 @@
script.setParents()
script.addToFlatList(items)
}
filterCollapsedCompositeBricks()
notifyDataSetChanged()
}

private fun filterCollapsedCompositeBricks() {

Check warning

Code scanning / detekt

Excessive nesting leads to hidden complexity. Prefer extracting code to make it easier to understand. Warning

Function filterCollapsedCompositeBricks is nested too deeply.

Check failure on line 132 in catroid/src/main/java/org/catrobat/catroid/ui/recyclerview/adapter/BrickAdapter.kt

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Refactor this method to reduce its Cognitive Complexity from 17 to the 15 allowed.

See more on https://sonarcloud.io/project/issues?id=Catrobat_Catroid&issues=AZ2OwcD6VfXNdCGJpqD2&open=AZ2OwcD6VfXNdCGJpqD2&pullRequest=5196
Comment thread
github-advanced-security[bot] marked this conversation as resolved.
Fixed
val filteredItems = ArrayList<Brick>()
var skipDepth = 0
var skipEndBricks = 0

for (item in items) {
if (skipDepth > 0) {
if (item is CompositeBrick) {
skipDepth++
skipEndBricks++
}
if (item is EndBrick) {
if (skipEndBricks > 0) {
skipEndBricks--
} else {
skipDepth--
}
}
continue
}

filteredItems.add(item)

if (item is CompositeBrick && item is BrickBaseType && (item as BrickBaseType).isCollapsed) {
skipDepth = 1
skipEndBricks = 0
}
}

items.clear()
items.addAll(filteredItems)
}

override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
val item = items[position]
val itemView = item.getView(parent.context)
Expand Down Expand Up @@ -150,9 +192,74 @@
}
item.checkBox.isChecked = selectionManager.isPositionSelected(position)
item.checkBox.isEnabled = viewStateManager.isEnabled(position)

addCollapseIndicator(item, itemView, brickViewContainer)

return itemView
}

private fun addCollapseIndicator(item: Brick, itemView: ViewGroup, brickViewContainer: View) {
// Remove any existing collapse indicator first
val existingIndicator = itemView.findViewWithTag<View>(COLLAPSE_INDICATOR_TAG)
if (existingIndicator != null) {
(existingIndicator.parent as? ViewGroup)?.removeView(existingIndicator)
}

val isCollapsed: Boolean

if (item is ScriptBrick) {
val script = item.script ?: return
isCollapsed = script.isCollapsed
} else if (item is CompositeBrick && item is BrickBaseType) {
isCollapsed = (item as BrickBaseType).isCollapsed
} else {
return
}

// Only show the indicator when collapsed
if (!isCollapsed) return

val context = itemView.context

// Check if the brickViewContainer is already wrapped in a FrameLayout
val containerParent = brickViewContainer.parent as? ViewGroup ?: return
val containerIndex = containerParent.indexOfChild(brickViewContainer)

val wrapper: android.widget.FrameLayout
if (containerParent is android.widget.FrameLayout && containerParent.tag == "collapse_wrapper") {
wrapper = containerParent
} else {
wrapper = android.widget.FrameLayout(context)
wrapper.tag = "collapse_wrapper"
val originalParams = brickViewContainer.layoutParams
containerParent.removeViewAt(containerIndex)
wrapper.layoutParams = originalParams
brickViewContainer.layoutParams = android.widget.FrameLayout.LayoutParams(
android.widget.FrameLayout.LayoutParams.MATCH_PARENT,
android.widget.FrameLayout.LayoutParams.WRAP_CONTENT
)
wrapper.addView(brickViewContainer)
containerParent.addView(wrapper, containerIndex)
}

val indicatorIcon = ImageView(context)
indicatorIcon.tag = COLLAPSE_INDICATOR_TAG

indicatorIcon.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.ic_collapse))
indicatorIcon.setColorFilter(
ContextCompat.getColor(context, android.R.color.white)
)

val size = (24 * context.resources.displayMetrics.density).toInt()

Check warning

Code scanning / detekt

Report magic numbers. Magic number is a numeric literal that is not defined as a constant and hence it's unclear what the purpose of this number is. It's better to declare such numbers as constants and give them a proper name. By default, -1, 0, 1, and 2 are not considered to be magic numbers. Warning

This expression contains a magic number. Consider defining it to a well named constant.
Comment thread
github-advanced-security[bot] marked this conversation as resolved.
Fixed
val margin = (8 * context.resources.displayMetrics.density).toInt()

Check warning

Code scanning / detekt

Report magic numbers. Magic number is a numeric literal that is not defined as a constant and hence it's unclear what the purpose of this number is. It's better to declare such numbers as constants and give them a proper name. By default, -1, 0, 1, and 2 are not considered to be magic numbers. Warning

This expression contains a magic number. Consider defining it to a well named constant.
Comment thread
github-advanced-security[bot] marked this conversation as resolved.
Fixed
val params = android.widget.FrameLayout.LayoutParams(size, size)
params.gravity = Gravity.CENTER_VERTICAL or Gravity.END
params.marginEnd = margin
indicatorIcon.layoutParams = params

wrapper.addView(indicatorIcon)
}

private fun checkBoxClickListener(item: Brick, itemView: ViewGroup, position: Int) {
item.checkBox.setOnClickListener { onCheckBoxClick(position) }
if (viewStateManager.isEnabled(position)) {
Expand All @@ -165,6 +272,7 @@
CONNECTED_ONLY -> handleCheckBoxModeConnectedOnly(item, itemView, position)
ALL -> handleCheckBoxModeAll(item)
SCRIPTS_ONLY -> handleCheckBoxModeScriptsOnly(item)
COLLAPSE_EXPAND -> handleCheckBoxModeAll(item)
}
}

Expand Down Expand Up @@ -348,6 +456,42 @@
notifyDataSetChanged()
}

fun selectAllCollapsedScripts() {
for (i in items.indices) {
val item = items[i]
if (item is ScriptBrick) {
val script = item.script
if (script != null && script.isCollapsed) {
selectionManager.setSelectionTo(true, i)
}
} else if (item is CompositeBrick && item is BrickBaseType) {

Check warning on line 467 in catroid/src/main/java/org/catrobat/catroid/ui/recyclerview/adapter/BrickAdapter.kt

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Merge this "if" statement with the nested one.

See more on https://sonarcloud.io/project/issues?id=Catrobat_Catroid&issues=AZ2OwcD6VfXNdCGJpqD3&open=AZ2OwcD6VfXNdCGJpqD3&pullRequest=5196
if ((item as BrickBaseType).isCollapsed) {
selectionManager.setSelectionTo(true, i)
}
}
}
notifyDataSetChanged()
}

fun toggleCollapseExpand(selectedItems: List<Brick>) {
for (brick in selectedItems) {
if (brick is ScriptBrick) {
val script = brick.script
if (script != null) {
script.isCollapsed = !script.isCollapsed
}
} else if (brick is CompositeBrick && brick is BrickBaseType) {
(brick as BrickBaseType).isCollapsed = !(brick as BrickBaseType).isCollapsed
}
}
updateItemsFromCurrentScripts()
}

private fun handleCheckBoxModeCollapseExpand(item: Brick) {

Check warning

Code scanning / detekt

Private function is unused and should be removed. Warning

Private function handleCheckBoxModeCollapseExpand is unused.

Check warning on line 490 in catroid/src/main/java/org/catrobat/catroid/ui/recyclerview/adapter/BrickAdapter.kt

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove this unused private "handleCheckBoxModeCollapseExpand" method.

See more on https://sonarcloud.io/project/issues?id=Catrobat_Catroid&issues=AZ2OwcD6VfXNdCGJpqD1&open=AZ2OwcD6VfXNdCGJpqD1&pullRequest=5196

Check warning on line 490 in catroid/src/main/java/org/catrobat/catroid/ui/recyclerview/adapter/BrickAdapter.kt

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Update this function so that its implementation is not identical to "handleCheckBoxModeAll" on line 285.

See more on https://sonarcloud.io/project/issues?id=Catrobat_Catroid&issues=AZ2OwcD6VfXNdCGJpqD0&open=AZ2OwcD6VfXNdCGJpqD0&pullRequest=5196
item.checkBox.visibility = View.VISIBLE
item.disableSpinners()
}

fun addItem(position: Int, item: Brick?) {
item?.let { items.add(position, it) }
notifyDataSetChanged()
Expand Down
Loading
Loading