package bluej.stride.generic;

import bluej.stride.framedjava.ast.HighlightedBreakpoint;
import bluej.stride.framedjava.ast.SlotFragment;
import bluej.stride.framedjava.canvases.JavaCanvas;
import bluej.stride.framedjava.elements.CodeElement;
import bluej.stride.framedjava.elements.SandwichCanvasesElement;
import bluej.stride.framedjava.frames.BlankFrame;
import bluej.stride.framedjava.frames.CodeFrame;
import bluej.stride.framedjava.frames.DebuggableFrame;
import bluej.stride.framedjava.frames.DebuggableParentFrame;
import bluej.stride.framedjava.frames.DebugInfo;
import bluej.stride.framedjava.frames.StrideDictionary;
import bluej.stride.framedjava.frames.GreenfootFrameUtil;
import bluej.stride.generic.ExtensionDescription.ExtensionSource;
import bluej.stride.operations.FrameOperation;
import bluej.stride.operations.PullUpContentsOperation;
import bluej.stride.slots.SlotLabel;
import bluej.utility.Utility;
import bluej.utility.javafx.JavaFXUtil;
import bluej.utility.javafx.SharedTransition;
import threadchecker.OnThread;
import threadchecker.Tag;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;


| Container-block representing a common parent for if/try/switch statements. | @author Amjad Altadmri | public abstract class SandwichCanvasesFrame extends MultiCanvasFrame implements CodeFrame<SandwichCanvasesElement>, DebuggableFrame{ private String stylePrefix; private String frameCaption; private final JavaCanvas firstCanvas; private String intermediateCanvasCaption; private final List<JavaCanvas> intermediateCanvases = new ArrayList<>(); private String tailCanvasCaption; private JavaCanvas tailCanvas; protected SandwichCanvasesElement element; protected final InteractionManager editor; private StrideDictionary dictionary = StrideDictionary.getDictionary();
| Default constructor. | | @param frameCaption | @param stylePrefix | protected SandwichCanvasesFrame(final InteractionManager editor, String frameCaption, String intermediateCanvasCaption, String tailCanvasCaption, String stylePrefix) { super(editor, frameCaption, stylePrefix); this.frameCaption = frameCaption; this.editor = editor; this.stylePrefix = stylePrefix; this.intermediateCanvasCaption = intermediateCanvasCaption; this.tailCanvasCaption = tailCanvasCaption; firstCanvas = new JavaCanvas(editor, this, stylePrefix, false); addCanvas(null, firstCanvas); } protected void addIntermediateCanvas() { addIntermediateCanvas(null, null); } private void addIntermediateCanvas(FrameCanvas canvas, FrameCursor cursor, int at) { List<Frame> contents = new ArrayList<>(); if (canvas != null && cursor != null) { while ( cursor.getFrameAfter() != null ) { contents.add(cursor.getFrameAfter()); cursor = cursor.getDown(); } contents.forEach(c -> canvas.removeBlock(c)); } addIntermediateCanvas(null, contents, at); } public void addIntermediateCanvas(List<SlotFragment> slots, List contents) { addIntermediateCanvas(slots, contents, canvases.size()); } private void addIntermediateCanvas(List<SlotFragment> slots, List contents, int at) { JavaCanvas intermediateCanvas = new JavaCanvas(editor, this, stylePrefix, false); if (contents != null) { intermediateCanvas.getFirstCursor().insertFramesAfter(contents); } final FrameContentRow intermediateHeader = getFrameContentRow(slots, intermediateCanvas, at - 1); addCanvas(intermediateHeader, intermediateCanvas, at); if (!intermediateHeader.focusLeftEndFromPrev()) intermediateCanvas.getFirstCursor().requestFocus(); intermediateCanvases.add(at - 1, intermediateCanvas); editor.modifiedFrame(this, false); } protected abstract FrameContentRow getFrameContentRow(List<SlotFragment> slots, JavaCanvas canvas, int at); protected void pullUpCanvasContents(FrameCursor cursor, FrameCanvas canvas) { canvas.getFirstCursor().getUp().requestFocus(); List<Frame> contents = new ArrayList<>(canvas.getBlockContents()); contents.forEach(frame -> { canvas.removeBlock(frame); frame.setParentCanvas(null); }); cursor.insertFramesAfter(contents); if (!contents.isEmpty()) { cursor.insertBlockAfter(new BlankFrame(editor)); } removeCanvas(canvas); editor.modifiedFrame(this, false); } public boolean addTailCanvas() { if (tailCanvas != null) { return false; } tailCanvas = new JavaCanvas(editor, this, stylePrefix, false); SlotLabel tailCanvasLabel = new SlotLabel(tailCanvasCaption); JavaFXUtil.addStyleClass(tailCanvasLabel, "divider-" + tailCanvasCaption); addCanvas(new FrameContentRow(this, tailCanvasLabel), tailCanvas); tailCanvas.getFirstCursor().requestFocus(); editor.modifiedFrame(this, false); return true; } private void addTailCanvas(FrameCanvas canvas, FrameCursor cursor) { if (addTailCanvas()) { List<Frame> contents = new ArrayList<>(); if (canvas != null && cursor != null) { while (cursor.getFrameAfter() != null){ contents.add(cursor.getFrameAfter()); cursor = cursor.getDown(); } contents.forEach(c -> canvas.removeBlock(c)); } tailCanvas.getFirstCursor().insertFramesAfter(contents); } } protected void removeCanvas(FrameCanvas canvas) { super.removeCanvas(canvas); if (intermediateCanvases.contains(canvas)){ intermediateCanvases.remove(canvas); } if (tailCanvas == canvas){ tailCanvas = null; } editor.modifiedFrame(this, false); } @Override public void regenerateCode() { List<CodeElement> firstCanvasContents = new ArrayList<>(); firstCanvas.getBlocksSubtype(CodeFrame.class).forEach(f -> { f.regenerateCode(); firstCanvasContents.add(f.getCode()); }); List<List<CodeElement>> intermediateCanvasesContents = Utility.mapList(intermediateCanvases, canvas -> Utility.mapList(canvas.getBlocksSubtype(CodeFrame.class), f -> { f.regenerateCode(); return f.getCode(); }) ); List<CodeElement> tailCanvasContents = null; if (tailCanvas != null) { tailCanvasContents = new ArrayList<>(); for (CodeFrame<?> f : tailCanvas.getBlocksSubtype(CodeFrame.class)) { f.regenerateCode(); tailCanvasContents.add(f.getCode()); } } element = regenerateCodeElement(firstCanvasContents, intermediateCanvasesContents, tailCanvasContents, frameEnabledProperty.get()); } protected abstract SandwichCanvasesElement regenerateCodeElement(List<CodeElement> firstCanvasContents, List<List<CodeElement>> intermediateCanvasesContents, List<CodeElement> tailCanvasContents, boolean enabled); @Override public SandwichCanvasesElement getCode() { return element; } public JavaCanvas getFirstCanvas() { return firstCanvas; } public JavaCanvas getTailCanvas() { return tailCanvas; } public DebuggableParentFrame getFirstCanvasDebug() { return new DebuggableParentFrame() { @Override @OnThread(Tag.FXPlatform) public HighlightedBreakpoint showDebugBefore(DebugInfo debug) { return ((JavaCanvas) getParentCanvas()).showDebugBefore(SandwichCanvasesFrame.this, debug); } @Override @OnThread(Tag.FXPlatform) public HighlightedBreakpoint showDebugAtEnd(DebugInfo debug) { return getFirstCanvas().showDebugBefore(null, debug); } @Override public FrameCanvas getParentCanvas() { return getFirstCanvas(); } }; } public DebuggableParentFrame getIntermediateCanvasDebug(int intermediateCanvasIndex) { return new DebuggableParentFrame() { @Override @OnThread(Tag.FXPlatform) public HighlightedBreakpoint showDebugBefore(DebugInfo debug) { return ((JavaCanvas)getParentCanvas()).showDebugBefore(SandwichCanvasesFrame.this, debug); } @Override @OnThread(Tag.FXPlatform) public HighlightedBreakpoint showDebugAtEnd(DebugInfo debug) { return intermediateCanvases.get(intermediateCanvasIndex).showDebugBefore(null, debug); } @Override public FrameCanvas getParentCanvas() { return intermediateCanvases.get(intermediateCanvasIndex); } }; } public DebuggableParentFrame getTailCanvasDebug() { return new DebuggableParentFrame() { @Override @OnThread(Tag.FXPlatform) public HighlightedBreakpoint showDebugBefore(DebugInfo debug) { return ((JavaCanvas)getParentCanvas()).showDebugBefore(SandwichCanvasesFrame.this, debug); } @Override @OnThread(Tag.FXPlatform) public HighlightedBreakpoint showDebugAtEnd(DebugInfo debug) { return getTailCanvas().showDebugBefore(null, debug); } @Override public FrameCanvas getParentCanvas() { return getTailCanvas(); } }; } @Override public boolean focusWhenJustAdded() { firstCanvas.getFirstCursor().requestFocus(); return true; } @Override public FrameTypeCheck check(FrameCanvas canvas) { return StrideDictionary.checkStatement(); } @Override public List getAvailableExtensions(FrameCanvas canvas, FrameCursor cursor) { List<ExtensionDescription> inners = new ArrayList<>(); inners.addAll(super.getAvailableExtensions(canvas, cursor)); if (canvas == firstCanvas) { inners.add(new ExtensionDescription('\b', "Remove " + frameCaption + ", keep contents", () -> new PullUpContentsOperation(editor).activate(getFrame()), false, ExtensionSource.INSIDE_FIRST)); } if ( canvas == firstCanvas || intermediateCanvases.contains(canvas) || canvas == null) { List<ExtensionSource> otherSources = new ArrayList<>(); otherSources.addAll(Arrays.asList(ExtensionSource.INSIDE_FIRST, ExtensionSource.INSIDE_LATER)); if (tailCanvas == null) otherSources.add(ExtensionSource.AFTER); inners.add(new ExtensionDescription(dictionary.getExtensionChar(intermediateCanvasCaption), "Add " + intermediateCanvasCaption, () -> { if (cursor == null) addIntermediateCanvas(); else{ addIntermediateCanvas(canvas, cursor, canvases.indexOf(canvas) + 1); } }, true, ExtensionSource.MODIFIER, otherSources.toArray(new ExtensionSource[0]))); } if (intermediateCanvases.contains(canvas)) { inners.add(new ExtensionDescription('\b', "Remove " + intermediateCanvasCaption + ", keep contents", () -> pullUpCanvasContents(getCursorBefore(canvas), canvas), false, ExtensionSource.INSIDE_FIRST)); } if ((canvas == null || Utility.findLast(getCanvases()).orElse(null) == canvas) && tailCanvas == null) { inners.add(new ExtensionDescription(dictionary.getExtensionChar(tailCanvasCaption), "Add " + tailCanvasCaption, () -> { if (cursor == null) addTailCanvas(); else{ addTailCanvas(canvas, cursor); } }, true, ExtensionSource.INSIDE_FIRST, ExtensionSource.INSIDE_LATER, ExtensionSource.MODIFIER, ExtensionSource.AFTER)); } if (tailCanvas != null && tailCanvas == canvas) { inners.add(new ExtensionDescription('\b', "Remove " + tailCanvasCaption + ", keep contents", () -> pullUpCanvasContents(getCursorBefore(canvas), canvas), false, ExtensionSource.INSIDE_FIRST)); } return inners; } @Override @OnThread(Tag.FXPlatform) public void setView(View oldView, View newView, SharedTransition animate) { super.setView(oldView, newView, animate); JavaFXUtil.setPseudoclass("bj-java-preview", newView == View.JAVA_PREVIEW, sidebar.getStyleable()); getCanvases().forEach(c -> { c.getCursors().forEach(cur -> cur.setView(newView, animate)); if (isFrameEnabled() && (oldView == View.JAVA_PREVIEW || newView == View.JAVA_PREVIEW)) c.previewCurly(newView == View.JAVA_PREVIEW, header.getLeftFirstItem(), null, animate); c.setView(oldView, newView, animate); }); } }

.   SandwichCanvasesFrame
.   addIntermediateCanvas
.   addIntermediateCanvas
.   addIntermediateCanvas
.   addIntermediateCanvas
.   getFrameContentRow
.   pullUpCanvasContents
.   addTailCanvas
.   addTailCanvas
.   removeCanvas
.   regenerateCode
.   regenerateCodeElement
.   getCode
.   getFirstCanvas
.   getTailCanvas
.   getFirstCanvasDebug
.   showDebugBefore
.   showDebugAtEnd
.   getParentCanvas
.   getIntermediateCanvasDebug
.   showDebugBefore
.   showDebugAtEnd
.   getParentCanvas
.   getTailCanvasDebug
.   showDebugBefore
.   showDebugAtEnd
.   getParentCanvas
.   focusWhenJustAdded
.   check
.   getAvailableExtensions
.   setView




456 neLoCode + 5 LoComm