diff --git a/resources/ui.xml b/resources/ui.xml index 8736a14..d5751e1 100644 --- a/resources/ui.xml +++ b/resources/ui.xml @@ -9,8 +9,9 @@ Size="1.0f, 1.0f" Name="Main Grid"> + Size="300, 60"> + > wholeText; + private int textHeight; + + @Override + public Point2 alignLine(String text, int line) { + int x = 0; + int y = (line + 1) * textHeight; + y += spacing * line; + return new Point2<>(x, y); + } + + @Override + public Point2 getPositionOnScreen(int x, int y){ + String currentLine = wholeText.get(y); + y = (fontMetrics.getHeight() + spacing) * y; + int width = 0; + for(int i = 1; i <= currentLine.length(); i++) { + width += fontMetrics.charWidth(currentLine.charAt(i - 1)); + if(x == i) { + return new Point2<>(width, y); + } + } + return new Point2<>(0, y); + } + + @Override + public Point2 getCaretPosition(int x, int y) { + y -= wholeText.size() * spacing; + y /= fontMetrics.getHeight(); + if(y > wholeText.size() - 1) { + return new Point2<>(wholeText.get(wholeText.size() - 1).length(), wholeText.size() - 1); + } + if(y < 0) { + return new Point2<>(0, 0); + } + String currentLine = wholeText.get(y); + for(int i = 0; i < currentLine.length(); i++) { + if(x < fontMetrics.charWidth(currentLine.charAt(i)) / 2) { + return new Point2<>(i, y); + } + x -= fontMetrics.charWidth(currentLine.charAt(i)); + } + return new Point2<>(currentLine.length(), y); + } + + public void setWholeText(List text) { + wholeText = new ArrayList<>(); + for(StringBuilder line: text) { + wholeText.add(line.toString()); + } + } + + @Override + public void setSpacing(int spacing) { + this.spacing = spacing; + } + + @Override + public void setFontMetrics(FontMetrics fontMetrics) { + this.fontMetrics = fontMetrics; + textHeight = fontMetrics.getHeight(); + } + + @Override + public void setSize(int width, int height) { + } +} diff --git a/src/guiTree/Components/Decoarations/RightTextAligner.java b/src/guiTree/Components/Decoarations/RightTextAligner.java new file mode 100644 index 0000000..fc66a64 --- /dev/null +++ b/src/guiTree/Components/Decoarations/RightTextAligner.java @@ -0,0 +1,83 @@ +package guiTree.Components.Decoarations; + +import guiTree.Helper.Point2; + +import java.awt.*; +import java.util.ArrayList; +import java.util.List; + +public class RightTextAligner implements TextAligner{ + private int spacing; + private FontMetrics fontMetrics; + private List wholeText; + private int textHeight; + private int width; + + @Override + public Point2 alignLine(String text, int line) { + int x = width - fontMetrics.stringWidth(text); + int y = (line + 1) * textHeight; + y += spacing * line; + return new Point2<>(x, y); + } + + @Override + public Point2 getCaretPosition(int x, int y) { + y -= wholeText.size() * spacing; + y /= fontMetrics.getHeight(); + if(y > wholeText.size() - 1) { + return new Point2<>(wholeText.get(wholeText.size() - 1).length(), wholeText.size() - 1); + } + if(y < 0) { + return new Point2<>(0, 0); + } + String currentLine = wholeText.get(y); + int index = currentLine.length(); + for(int i = width - currentLine.length(); i < width; i++) { + if(x > width - fontMetrics.charWidth(currentLine.charAt(index - 1))) { + return new Point2<>(index, y); + } + x += fontMetrics.charWidth(currentLine.charAt(index - 1)); + index--; + } + return new Point2<>(0, y); + } + + @Override + public Point2 getPositionOnScreen(int x, int y) { + String currentLine = wholeText.get(y); + y = (fontMetrics.getHeight() + spacing) * y; + int width = this.width; + for(int i = currentLine.length(); i > 0; i--) { + if(x == i) { + return new Point2<>(width, y); + } + width -= fontMetrics.charWidth(currentLine.charAt(i - 1)); + } + return new Point2<>(this.width - fontMetrics.stringWidth(currentLine), y); + } + + @Override + public void setWholeText(List wholeText) { + this.wholeText = new ArrayList<>(); + for(StringBuilder line: wholeText) { + this.wholeText.add(line.toString()); + } + } + + @Override + public void setSpacing(int spacing) { + this.spacing = spacing; + } + + @Override + public void setFontMetrics(FontMetrics fontMetrics) { + this.fontMetrics = fontMetrics; + textHeight = fontMetrics.getHeight(); + } + + @Override + public void setSize(int width, int height) { + this.width = width; + } +} diff --git a/src/guiTree/Components/Decoarations/TextAligner.java b/src/guiTree/Components/Decoarations/TextAligner.java new file mode 100644 index 0000000..b1107a1 --- /dev/null +++ b/src/guiTree/Components/Decoarations/TextAligner.java @@ -0,0 +1,16 @@ +package guiTree.Components.Decoarations; + +import guiTree.Helper.Point2; + +import java.awt.*; +import java.util.List; + +public interface TextAligner { + Point2 alignLine(String text, int line); + Point2 getCaretPosition(int x, int y); + Point2 getPositionOnScreen(int x, int y); + void setWholeText(List wholeText); + void setSpacing(int spacing); + void setFontMetrics(FontMetrics fontMetrics); + void setSize(int width, int height); +} diff --git a/src/guiTree/Components/InputTextBox.java b/src/guiTree/Components/InputTextBox.java index 42d3c26..0eba7b0 100644 --- a/src/guiTree/Components/InputTextBox.java +++ b/src/guiTree/Components/InputTextBox.java @@ -125,7 +125,12 @@ public class InputTextBox extends Visual { } return; } - caretPosition.x --; + if(keyEvent.isControlDown()) { + moveCaretToNextWord(-1); + } + else { + caretPosition.x--; + } if(!keyEvent.isShiftDown()) { startDragPosition = new Point2<>(caretPosition); } @@ -148,7 +153,12 @@ public class InputTextBox extends Visual { } return; } - caretPosition.x ++; + if(keyEvent.isControlDown()) { + moveCaretToNextWord(1); + } + else { + caretPosition.x++; + } if(!keyEvent.isShiftDown()) { startDragPosition = new Point2<>(caretPosition); } @@ -311,6 +321,46 @@ public class InputTextBox extends Visual { return new Point2<>(currentLine.length(), y); } + private void moveCaretToNextWord(int direction) { + if(direction > 0) { + if (lines.get(caretPosition.y).length() == caretPosition.x) { + if (lines.size() > caretPosition.y + 1) { + caretPosition.y++; + caretPosition.x = 0; + return; + } + } + } + else { + if (caretPosition.x == 0) { + if (caretPosition.y > 0) { + caretPosition.y--; + caretPosition.x = lines.get(caretPosition.y).length(); + return; + } + } + } + StringBuilder currentLine = lines.get(caretPosition.y); + char currentChar; + currentChar = currentLine.charAt(caretPosition.x + direction); + while(currentChar == ' ' ){ + caretPosition.x += direction; + currentChar = currentLine.charAt(caretPosition.x); + if((currentLine.length() == caretPosition.x && direction > 0) || (caretPosition.x == 0 && direction < 0)) { + return; + } + } + do { + caretPosition.x += direction; + if(currentLine.length() == caretPosition.x && direction > 0) { + return; + } + currentChar = currentLine.charAt(caretPosition.x); + if(caretPosition.x == 0 && direction < 0) { + return; + } + } while((currentChar >= 'a' && currentChar <= 'z') || (currentChar >= 'A' && currentChar <= 'Z')); + } private void deleteSelection() { selectionRectangles.clear(); diff --git a/src/guiTree/Components/Text.java b/src/guiTree/Components/Text.java index 3c905d7..1c34a98 100644 --- a/src/guiTree/Components/Text.java +++ b/src/guiTree/Components/Text.java @@ -1,185 +1,330 @@ package guiTree.Components; +import guiTree.Components.Decoarations.LeftTextAligner; +import guiTree.Components.Decoarations.RightTextAligner; +import guiTree.Components.Decoarations.TextAligner; +import guiTree.Helper.Point2; +import guiTree.Helper.Point4; import guiTree.Visual; +import guiTree.events.KeyAdapter; import guiTree.events.MouseAdapter; import java.awt.*; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.StringSelection; +import java.awt.datatransfer.Transferable; +import java.awt.datatransfer.UnsupportedFlavorException; +import java.awt.event.KeyEvent; import java.awt.event.MouseEvent; import java.awt.image.BufferedImage; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; public class Text extends Visual { - private String text; - private boolean selectable; - private int startIndex; - private int endIndex; - private int textWidth; - private int textHeight; - private boolean inside; - private int[] characterWidthMap; + private List lines; + private String title; + private Point2 caretPosition; + private Point2 startDragPosition; + private List selectedText; + private List> selectionRectangles; private FontMetrics fontMetrics; - private int textX; - private int textY; + private TextAligner textAligner; + private int paragraphSpacing; + private boolean selectable; public Text() { - this(0, 0, ""); + this(true, ""); } - public Text(int x, int y, String text) { - super(x, y); - this.text = text; - inside = false; - characterWidthMap = new int[text.length()]; - startIndex = -1; - endIndex = -1; - textX = 0; - textY = 0; + public Text(Boolean visible) { + this(visible, ""); + } + + public Text(String title) { + this(true, title); + } + + public Text(Boolean visible, String title) { + super(); + this.title = title; + lines = new ArrayList<>(); + selectionRectangles = new ArrayList<>(); + lines.add(new StringBuilder()); + caretPosition = new Point2<>(0, 0); + startDragPosition = new Point2<>(0, 0); + textAligner = new LeftTextAligner(); + paragraphSpacing = 1; + selectable = true; + selectedText = new ArrayList<>(); addMouseListener(new MouseAdapter() { @Override - public void mousePressed(MouseEvent mouseEvent) { - int x = mouseEvent.getX(); - int y = mouseEvent.getY(); - if(isOverText(x, y)) { - startIndex = getCharAt(x); - System.out.println("Start Index: " + startIndex); - return; - } - startIndex = -1; - endIndex = -1; + public void mouseDragged(MouseEvent mouseEvent) { + caretPosition = getCaretPosition(mouseEvent.getX(), mouseEvent.getY()); + setSelection(); update(); } - @Override - public void mouseDragged(MouseEvent mouseEvent) { - int x = mouseEvent.getX(); - int y = mouseEvent.getY(); - - if(startIndex != -1) { - endIndex = getCharAt(x); - System.out.println("End index: " + endIndex); + public void mousePressed(MouseEvent mouseEvent) { + caretPosition = getCaretPosition(mouseEvent.getX(), mouseEvent.getY()); + startDragPosition = new Point2<>(caretPosition.x, caretPosition.y); + setSelection(); + } + @Override + public void mouseEntered(MouseEvent mouseEvent) { + if(selectable) { + setCursor(new Cursor(Cursor.TEXT_CURSOR)); } - update(); } @Override public void mouseExited(MouseEvent mouseEvent) { - if(inside) { - setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); - } + setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); } + }); + addKeyListener(new KeyAdapter() { @Override - public void mouseMoved(MouseEvent mouseEvent) { - int x = mouseEvent.getX(); - int y = mouseEvent.getY(); - if(isOverText(x, y)) { - if(!inside) { - setCursor(new Cursor(Cursor.TEXT_CURSOR)); - inside = true; + public void keyPressed(KeyEvent keyEvent) { + if(keyEvent.getKeyCode() == KeyEvent.VK_C) { + if(keyEvent.isControlDown()) { + copyToClipboard(); + return; } - return; } - if(inside) { - setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); - inside = false; + + if(keyEvent.getKeyCode() == KeyEvent.VK_V) { + if(keyEvent.isControlDown()) { + pasteFromClipboard(); + update(); + return; + } + } + + if(keyEvent.getKeyCode() == KeyEvent.VK_A) { + if(keyEvent.isControlDown()) { + selectAll(); + update(); + } } } }); } - public String getText() { - return text; - } - - public void setText(String text) { - this.text = text; - characterWidthMap = new int[text.length()]; - } - - public void setSelectable(Boolean selectable) { - this.selectable = selectable; - } - - private int getCharAt(int x) { - int location = (getWidth() - textWidth)/2; - for(int i = 0; i < text.length(); i++) { - if(x < location + characterWidthMap[i] / 2) { - return i; - } - location += characterWidthMap[i]; - } - return text.length()-1; - } - @Override public void setFont(Font font) { super.setFont(font); fontMetrics = null; } - private boolean isOverText(int x, int y) { - if(x < textX || x > textX + textWidth) { - return false; - } - if(y > textY || y < textY - textHeight) { - return false; - } - System.out.println("Text X: " + textX + " Text Y: " + textY + " x: " + x + " y: " + y + " textWidth: " + textWidth + " textHeight: " + textHeight); - return true; + @Override + public void setSize() { + super.setSize(); + textAligner.setSize(getWidth(), getHeight()); } - private void setCharacterWidthMap() { - for(int i = 0; i < text.length(); i++) { - int charWidth = fontMetrics.charWidth(text.charAt(i)); - characterWidthMap[i] = charWidth; - } - textWidth = fontMetrics.stringWidth(text); - textHeight = fontMetrics.getHeight(); - textX = (getWidth() - textWidth)/2; - textY = (getHeight() + textHeight)/2; + public void setSpacing(int spacing) { + this.paragraphSpacing = spacing; + textAligner.setSpacing(spacing); } + public void setSelectable(boolean selectable) { + this.selectable = selectable; + } + public void setText(String text) { + lines.clear(); + int lineIndex = text.indexOf('\n'); + while(lineIndex != -1) { + lines.add(new StringBuilder(text.substring(0, lineIndex))); + text = text.substring(lineIndex + 1); + lineIndex = text.indexOf('\n'); + } + lines.add(new StringBuilder(text)); + textAligner.setWholeText(lines); + update(); + } + + public void setAlignment(String textAlignment) { + textAlignment = textAlignment.toLowerCase(); + if(textAlignment.equals("left")) { + textAligner = new LeftTextAligner(); + textAligner.setWholeText(lines); + textAligner.setSize(getWidth(), getHeight()); + textAligner.setSpacing(paragraphSpacing); + return; + } + if(textAlignment.equals("right")) { + textAligner = new RightTextAligner(); + textAligner.setWholeText(lines); + textAligner.setSize(getWidth(), getHeight()); + textAligner.setSpacing(paragraphSpacing); + return; + } + System.err.println("Alignment does not exist"); + } + + private void copyToClipboard() { + StringBuilder clipboardText = new StringBuilder(); + for(StringBuilder line: selectedText) { + clipboardText.append(line).append('\n'); + } + StringSelection stringSelection = new StringSelection(clipboardText.toString()); + Toolkit.getDefaultToolkit().getSystemClipboard().setContents(stringSelection, null); + } + + private void selectAll() { + caretPosition.x = lines.get(lines.size() - 1).length(); + caretPosition.y = lines.size() - 1; + startDragPosition.x = 0; + startDragPosition.y = 0; + setSelection(); + } + + private void pasteFromClipboard() { + Transferable clipboardTransferable = Toolkit.getDefaultToolkit().getSystemClipboard().getContents(this); + String clipboardText = null; + try { + clipboardText = (String) clipboardTransferable.getTransferData(DataFlavor.stringFlavor); + } catch (UnsupportedFlavorException | IOException e) { + e.printStackTrace(); + } + if(clipboardText == null) { + return; + } + clipboardText = clipboardText.substring(0, clipboardText.length() -1 ); + if(clipboardText.indexOf('\n') == -1) { + lines.get(caretPosition.y).insert(caretPosition.x, clipboardText); + caretPosition.x += clipboardText.length(); + startDragPosition = caretPosition; + } + } + + private Point2 getPositionOnScreen(int x, int y){ + return textAligner.getPositionOnScreen(x, y); + } + + private Point2 getCaretPosition(int x, int y) { + return textAligner.getCaretPosition(x, y); + } + + private void deleteSelection() { + selectionRectangles.clear(); + selectedText.clear(); + + if(caretPosition.equals(startDragPosition)) { + return; + } + Point2 selectionStart; + Point2 selectionEnd; + if(caretPosition.compareTo(startDragPosition) < 0) { + selectionStart = new Point2<>(caretPosition); + selectionEnd = new Point2<>(startDragPosition); + } + else { + selectionStart = new Point2<>(startDragPosition); + selectionEnd = new Point2<>(caretPosition); + } + caretPosition = selectionStart; + + if(selectionStart.y.equals(selectionEnd.y)) { + StringBuilder currentLine = lines.get(selectionStart.y); + int lineLength = currentLine.length(); + int newLength = lineLength - selectionEnd.x + selectionStart.x; + currentLine.insert(selectionStart.x, currentLine.substring(selectionEnd.x)); + currentLine = new StringBuilder(currentLine.substring(0, newLength)); + lines.set(selectionStart.y, currentLine); + return; + } + + while(selectionStart.y + 1 < selectionEnd.y) { + lines.remove(selectionStart.y + 1); + selectionEnd.y--; + } + + StringBuilder currentLine = lines.get(selectionStart.y); + currentLine.insert(selectionStart.x, lines.get(selectionEnd.y).substring(selectionEnd.x)); + currentLine = new StringBuilder(currentLine.substring(0, selectionStart.x + lines.get(selectionEnd.y).substring(selectionEnd.x).length())); + lines.remove((int)selectionEnd.y); + lines.set(selectionStart.y, currentLine); + } + + private void setSelection() { + if(!selectable) { + return; + } + selectedText.clear(); + selectionRectangles.clear(); + System.out.println(caretPosition + " " + startDragPosition); + if(caretPosition.equals(startDragPosition)) { + return; + } + Point2 selectionStart; + Point2 selectionEnd; + if(caretPosition.compareTo(startDragPosition) < 0) { + selectionStart = new Point2<>(caretPosition); + selectionEnd = new Point2<>(startDragPosition); + } + else { + selectionStart = new Point2<>(startDragPosition); + selectionEnd = new Point2<>(caretPosition); + } + + if(selectionEnd.y.equals(selectionStart.y)) { + selectedText.add(new StringBuilder()); + Point2 startRect = getPositionOnScreen(selectionStart.x, selectionStart.y); + Point2 endRect = getPositionOnScreen(selectionEnd.x, selectionEnd.y); + selectionRectangles.add(new Point4<>(startRect.x, startRect.y + 3, endRect.x, endRect.y + fontMetrics.getHeight() + 3)); + StringBuilder currentLine = lines.get(selectionStart.y); + for(int x = selectionStart.x; x < selectionEnd.x; x++) { + selectedText.get(0).insert(selectedText.get(0).length(), currentLine.charAt(x)); + } + return; + } + + for(int y = selectionStart.y; y < selectionEnd.y; y++) { + StringBuilder currentLine = lines.get(y); + Point2 startRect = getPositionOnScreen(selectionStart.x, y); + Point2 endRect = getPositionOnScreen(currentLine.length(), y); + selectionRectangles.add(new Point4<>(startRect.x, startRect.y + 3, endRect.x, endRect.y + fontMetrics.getHeight() + 3)); + selectedText.add(new StringBuilder()); + int selectionIndex = 0; + for(int x = selectionStart.x; x < currentLine.length(); x++) { + selectedText.get(selectedText.size() - 1).insert(selectionIndex++, currentLine.charAt(x)); + } + selectionStart.x = 0; + } + StringBuilder currentLine = lines.get(selectionEnd.y); + selectedText.add(new StringBuilder()); + Point2 startRect = getPositionOnScreen(selectionStart.x, selectionEnd.y); + Point2 endRect = getPositionOnScreen(selectionEnd.x, selectionEnd.y); + selectionRectangles.add(new Point4<>(startRect.x, startRect.y + 3, endRect.x, endRect.y + fontMetrics.getHeight() + 3)); + int selectionIndex = 0; + for(int x = 0; x < selectionEnd.x; x++) { + selectedText.get(selectedText.size() - 1).insert(selectionIndex++, currentLine.charAt(x)); + } + } + + @Override public void paint(BufferedImage imageBuffer) { Graphics2D g = imageBuffer.createGraphics(); - - if(getFont() != null) { - g.setFont(getFont()); - } if(fontMetrics == null) { fontMetrics = g.getFontMetrics(); - setCharacterWidthMap(); + textAligner.setFontMetrics(fontMetrics); } - if(startIndex != -1 && endIndex != -1) { - int startX; - int endX; - if(startIndex > endIndex) { - endX = startIndex - 1; - startX = endIndex; - } - else { - startX = startIndex; - endX = endIndex; - } - int highlightStartX = textX; - int highlightEndX = textX; - - for(int i = 0; i <= endX; i++) { - if(i < startX) { - highlightStartX += characterWidthMap[i]; - } - highlightEndX += characterWidthMap[i]; - } - + if(selectable) { g.setColor(Color.BLUE); - g.fillRect(highlightStartX, textY - textHeight + 3, highlightEndX - highlightStartX, textHeight); + for (Point4 rect : selectionRectangles) { + g.fillRect(rect.a, rect.b, rect.c - rect.a, rect.d - rect.b + paragraphSpacing); + } } g.setColor(getFontColor()); - - g.drawString(text, textX, textY); - - g.dispose(); + for(StringBuilder line: lines) { + Point2 position = textAligner.alignLine(line.toString(), lines.indexOf(line)); + g.drawString(line.toString(), position.x, position.y); + } } } diff --git a/src/guiTree/Helper/Debugger.java b/src/guiTree/Helper/Debugger.java index 8e8f4fa..472386e 100644 --- a/src/guiTree/Helper/Debugger.java +++ b/src/guiTree/Helper/Debugger.java @@ -2,7 +2,7 @@ package guiTree.Helper; public class Debugger { public enum Tag { - LISTENER(true), + LISTENER(false), PAINTING(false), FPS(false), ANIMATIONS(false), diff --git a/src/guiTree/Visual.java b/src/guiTree/Visual.java index fa1f672..7a074b1 100644 --- a/src/guiTree/Visual.java +++ b/src/guiTree/Visual.java @@ -1,6 +1,7 @@ package guiTree; import guiTree.Animations.AnimationInterface; +import guiTree.Components.Decoarations.Decoration; import guiTree.Helper.Debugger; import guiTree.Helper.Point2; import guiTree.Helper.Timer; @@ -337,15 +338,27 @@ public class Visual { } public void addVisual(Visual child) { - this.children.add(child); + children.add(child); child.setParent(this); child.setLocation(); child.setSize(); - if(this.active) { + if(active) { child.activate(); } - update(); + child.update(); + } + + public void addVisual(Decoration decoration) { + children.add(decoration); + ((Visual)decoration).setParent(this); + decoration.setLocation(); + decoration.setSize(); + + if(active) { + ((Visual)decoration).activate(); + } + decoration.update(); } public void removeVisual(Visual child) { @@ -410,7 +423,7 @@ public class Visual { timer.startTiming(); clearImageBuffer(); - this.paint(imageBuffer); + paint(imageBuffer); for (Visual v : children) { if (v.dirty && v.active) { v.revalidate(); diff --git a/src/parser/XAMLParser.java b/src/parser/XAMLParser.java index 787054c..432cc23 100644 --- a/src/parser/XAMLParser.java +++ b/src/parser/XAMLParser.java @@ -1,6 +1,7 @@ package parser; import com.sun.jdi.InvalidTypeException; +import guiTree.Components.Decoarations.Decoration; import parser.converters.Converter; import guiTree.Helper.Debugger; import guiTree.Visual; @@ -46,7 +47,6 @@ public class XAMLParser { } try { Method method = object.getClass().getMethod(methodName, parameterTypes); - assert method != null; method.invoke(object, parameterList.toArray()); } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { e.printStackTrace(); @@ -126,7 +126,7 @@ public class XAMLParser { } Debugger.log("Parsing " + parentClass, Debugger.Tag.PARSING); Object parentObject = parentClass.getDeclaredConstructor().newInstance(); - Debugger.log("Constructor called succesfuly for " + parentObject, Debugger.Tag.PARSING); + Debugger.log("Constructor called successfully for " + parentObject, Debugger.Tag.PARSING); setAttributes(parentObject, parentNode.getAttributes()); @@ -139,9 +139,17 @@ public class XAMLParser { Object childObject = parseNode(childNode); - if(parentObject instanceof Visual && childObject instanceof Visual) { - Debugger.log("Adding " + childObject + " to " + parentObject, Debugger.Tag.PARSING); - addVisual((Visual) parentObject, (Visual) childObject); + if(parentObject instanceof Visual) { + if(childObject instanceof Decoration) { + Debugger.log("Adding decoration " + childObject + " to " + parentObject, Debugger.Tag.PARSING); + ((Visual)parentObject).addVisual((Decoration) childObject); + } + else { + if (childObject instanceof Visual) { + Debugger.log("Adding " + childObject + " to " + parentObject, Debugger.Tag.PARSING); + addVisual((Visual) parentObject, (Visual) childObject); + } + } } } }