From 9bd4e3a87ca931af87c4d88b09f25fa1090eed38 Mon Sep 17 00:00:00 2001 From: Thibaud Date: Sat, 29 Sep 2018 23:48:08 +0200 Subject: [PATCH] Squashed 'shapes/' content from commit 0f9f944 git-subtree-dir: shapes git-subtree-split: 0f9f944deb15275858fadb5e133a8d14e46a640f --- .classpath | 6 + .gitignore | 21 ++ .project | 17 + .settings/org.eclipse.jdt.core.prefs | 11 + README.md | 3 + index.html | 20 ++ src/fr/uha/.DS_Store | Bin 0 -> 6148 bytes src/fr/uha/graphics/shapes/.DS_Store | Bin 0 -> 12292 bytes src/fr/uha/graphics/shapes/SCircle.java | 81 +++++ src/fr/uha/graphics/shapes/SCollection.java | 103 ++++++ src/fr/uha/graphics/shapes/SRectangle.java | 66 ++++ src/fr/uha/graphics/shapes/SSelection.java | 35 ++ src/fr/uha/graphics/shapes/SText.java | 89 +++++ src/fr/uha/graphics/shapes/STriangle.java | 80 +++++ src/fr/uha/graphics/shapes/Shape.java | 63 ++++ src/fr/uha/graphics/shapes/ShapeVisitor.java | 15 + .../shapes/attributes/Attributes.java | 5 + .../shapes/attributes/ColorAttributes.java | 48 +++ .../shapes/attributes/FontAttributes.java | 34 ++ .../attributes/SelectionAttributes.java | 33 ++ src/fr/uha/graphics/shapes/ui/.DS_Store | Bin 0 -> 6148 bytes src/fr/uha/graphics/shapes/ui/Editor.java | 210 ++++++++++++ .../uha/graphics/shapes/ui/ShapeDraftman.java | 161 +++++++++ .../graphics/shapes/ui/ShapesController.java | 321 ++++++++++++++++++ src/fr/uha/graphics/shapes/ui/ShapesView.java | 37 ++ .../shapes/ui/menu/MenuAddListener.java | 59 ++++ .../shapes/ui/menu/MenuEditListener.java | 115 +++++++ src/fr/uha/graphics/ui/.DS_Store | Bin 0 -> 6148 bytes src/fr/uha/graphics/ui/Controller.java | 73 ++++ src/fr/uha/graphics/ui/View.java | 34 ++ style.css | 8 + 31 files changed, 1748 insertions(+) create mode 100755 .classpath create mode 100644 .gitignore create mode 100755 .project create mode 100755 .settings/org.eclipse.jdt.core.prefs create mode 100644 README.md create mode 100644 index.html create mode 100755 src/fr/uha/.DS_Store create mode 100755 src/fr/uha/graphics/shapes/.DS_Store create mode 100755 src/fr/uha/graphics/shapes/SCircle.java create mode 100755 src/fr/uha/graphics/shapes/SCollection.java create mode 100755 src/fr/uha/graphics/shapes/SRectangle.java create mode 100644 src/fr/uha/graphics/shapes/SSelection.java create mode 100755 src/fr/uha/graphics/shapes/SText.java create mode 100644 src/fr/uha/graphics/shapes/STriangle.java create mode 100755 src/fr/uha/graphics/shapes/Shape.java create mode 100755 src/fr/uha/graphics/shapes/ShapeVisitor.java create mode 100755 src/fr/uha/graphics/shapes/attributes/Attributes.java create mode 100755 src/fr/uha/graphics/shapes/attributes/ColorAttributes.java create mode 100755 src/fr/uha/graphics/shapes/attributes/FontAttributes.java create mode 100755 src/fr/uha/graphics/shapes/attributes/SelectionAttributes.java create mode 100755 src/fr/uha/graphics/shapes/ui/.DS_Store create mode 100755 src/fr/uha/graphics/shapes/ui/Editor.java create mode 100755 src/fr/uha/graphics/shapes/ui/ShapeDraftman.java create mode 100644 src/fr/uha/graphics/shapes/ui/ShapesController.java create mode 100755 src/fr/uha/graphics/shapes/ui/ShapesView.java create mode 100644 src/fr/uha/graphics/shapes/ui/menu/MenuAddListener.java create mode 100644 src/fr/uha/graphics/shapes/ui/menu/MenuEditListener.java create mode 100755 src/fr/uha/graphics/ui/.DS_Store create mode 100755 src/fr/uha/graphics/ui/Controller.java create mode 100755 src/fr/uha/graphics/ui/View.java create mode 100644 style.css diff --git a/.classpath b/.classpath new file mode 100755 index 0000000..fceb480 --- /dev/null +++ b/.classpath @@ -0,0 +1,6 @@ + + + + + + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..cdd27a2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,21 @@ +!/src/ +/bin/ +*.class +*.log* + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.ear + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +.DS_Store + +# Ignore automatically generated HTML and CSS +*.html +*.css diff --git a/.project b/.project new file mode 100755 index 0000000..c51b6c7 --- /dev/null +++ b/.project @@ -0,0 +1,17 @@ + + + Shapes + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs new file mode 100755 index 0000000..3a21537 --- /dev/null +++ b/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,11 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.8 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/README.md b/README.md new file mode 100644 index 0000000..13602df --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# Shapes + +la classe \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 0000000..b024700 --- /dev/null +++ b/index.html @@ -0,0 +1,20 @@ + + + + + +TP Shape COLICCHIO et GASSER + + + +
+
+
+
+
hello
+
+ + + diff --git a/src/fr/uha/.DS_Store b/src/fr/uha/.DS_Store new file mode 100755 index 0000000000000000000000000000000000000000..d526513bbd05241a7dc70618fa4b87e234fbcc9c GIT binary patch literal 6148 zcmeHK%}N773{Gkf3toEkI8Pw@21}_=&==6%Vl6DLSiCRzWgnh&5myHej-Dzpe*j?PMXZz$`ThQ*&D2y9uKwzId0`S3e24_)Pw*wx;yLcjRpx^s5Lr1%* zNGbXSlJ6yXFPZtl%u7ThO}5J$k)enTP*sx}2Z|0Koa%-1B{b<8^Rk-5*2Ugq?%YM6 zy(e2)-<8$k%k#f}Sg}_ypXFvz&a0}_5gS-Nug7~q<~b`jJH^rXtQU_}_%syz?cCF< znH!6|UBApM&SHJ@_7VE~eYIOp8YDmhBtQZra1;SgQZl$YDvHh|Kmz}Pfc_scs%jBh zyV|bntdZM)gTaW)5lS7Np+7&Y>$wQ$Yn&OI)JRIXW{EE=p)x#yl"; + } + + @Override + public String cssShape() { + StringBuilder strBuilder = new StringBuilder(".circle" + this.hashCode() + "{ "); + strBuilder.append("position: absolute;"); + strBuilder.append("top:" + this.loc.y + "px;"); + strBuilder.append("left:" + this.loc.x + "px;"); + strBuilder.append("width:" + this.radius + "px;"); + strBuilder.append("height:" + this.radius + "px;"); + strBuilder.append("border-radius:" + this.radius/2 + "px;"); + strBuilder.append("-webkit-border-radius:" + this.radius/2 + "px;"); + strBuilder.append("-o-border-radius:" + this.radius/2 + "px;"); + strBuilder.append("-moz-border-radius:" + this.radius/2 + "px;"); + strBuilder.append(this.attributesCss()); + strBuilder.append(" }"); + return strBuilder.toString(); + } + +} diff --git a/src/fr/uha/graphics/shapes/SCollection.java b/src/fr/uha/graphics/shapes/SCollection.java new file mode 100755 index 0000000..c45e452 --- /dev/null +++ b/src/fr/uha/graphics/shapes/SCollection.java @@ -0,0 +1,103 @@ +package fr.uha.graphics.shapes; + +import java.awt.Point; +import java.awt.Rectangle; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.logging.Logger; + +import fr.uha.graphics.shapes.attributes.Attributes; +import fr.uha.graphics.shapes.ui.Editor; + +public class SCollection extends Shape { + + private static final Logger LOGGER = Logger.getLogger(SCollection.class.getName()); + + private List childShapes = new ArrayList(); + private Point loc; + + public Iterator getIterator() { + return childShapes.listIterator(); + } + + public void add(Shape s) { + // LOGGER.log(Level.INFO, "Adding to collection : {0}", s.toString()); + childShapes.add(s); + relocate(); + } + + public void remove(Shape s) { + if (childShapes.remove(s)) relocate(); + } + + @Override + public Point getLoc() { + return this.loc; + } + + @Override + public void setLoc(Point p) { + this.loc = p; + } + + @Override + public void translate(int dx, int dy) { + for (Shape s : this.childShapes) { + s.translate(dx, dy); + } + relocate(); + } + + @Override + public void addAttributes(Attributes attrs) { + super.addAttributes(attrs); + // Propagate all atrributes to the members of SCollection. + for (Shape s : this.childShapes) s.addAttributes(attrs); + } + + @Override + public Rectangle getBounds() { + Rectangle bounds; + try { + bounds = childShapes.get(0).getBounds(); + for (Shape s : childShapes) + bounds = bounds.union(s.getBounds()); + } catch (IndexOutOfBoundsException e){ + // If the SCollection is empty, set the bounds to fill the window + return new Rectangle(Editor.WIN_SIZE); + } + return bounds; + } + + @Override + public void accept(ShapeVisitor sv) { + sv.visitCollection(this); + } + + private void relocate() { + // Recalculate the location of the SCollection (Upper-left corner) + this.loc = this.getBounds().getLocation(); + } + + @Override + public String htmlShape() { + StringBuilder prepare= new StringBuilder(); + for(Iterator it=childShapes.iterator();it.hasNext();){ + Shape current = it.next(); + prepare.append(current.htmlShape()); + } + return prepare.toString(); + } + + @Override + public String cssShape() { + StringBuilder prepare= new StringBuilder(); + for(Iterator it=childShapes.iterator();it.hasNext();){ + Shape current = it.next(); + prepare.append(current.cssShape()); + } + return prepare.toString(); + } + +} diff --git a/src/fr/uha/graphics/shapes/SRectangle.java b/src/fr/uha/graphics/shapes/SRectangle.java new file mode 100755 index 0000000..ef57ecb --- /dev/null +++ b/src/fr/uha/graphics/shapes/SRectangle.java @@ -0,0 +1,66 @@ +package fr.uha.graphics.shapes; + +import java.awt.Point; +import java.awt.Rectangle; + +import fr.uha.graphics.shapes.attributes.ColorAttributes; + +public class SRectangle extends Shape { + private Rectangle rect; + + public SRectangle(Point loc, int width, int length) { + this.rect = new Rectangle(loc.x, loc.y, width, length); + } + + public Rectangle getRect() { + return this.rect; + } + + @Override + public Point getLoc() { + return this.rect.getLocation(); + } + + @Override + public void setLoc(Point p) { + this.rect.setLocation(p); + } + + @Override + public void translate(int dx, int dy) { + this.rect.translate(dx, dy); + + } + + @Override + public Rectangle getBounds() { + return this.rect.getBounds(); + } + + @Override + public void accept(ShapeVisitor sv) { + sv.visitRectangle(this); + } + + @Override + public String toString() { + return "SRectangle [x=" + rect.x + " y=" + rect.y + " height=" + rect.height + " width=" + rect.width + "]"; + } + + @Override + public String htmlShape() { + return "
"; + } + + @Override + public String cssShape() { + StringBuilder strBuilder = new StringBuilder(".rectangle" + this.hashCode() + "{ "); + strBuilder.append("position:absolute;"); + strBuilder.append("top:" + this.getLoc().y + "px;"); + strBuilder.append("left:" + this.getLoc().x + "px;"); + strBuilder.append("width:" + this.rect.width + "px;"); + strBuilder.append("height:" + this.rect.height + "px;"); + strBuilder.append(this.attributesCss() + " }"); + return strBuilder.toString(); + } +} diff --git a/src/fr/uha/graphics/shapes/SSelection.java b/src/fr/uha/graphics/shapes/SSelection.java new file mode 100644 index 0000000..e85d5c2 --- /dev/null +++ b/src/fr/uha/graphics/shapes/SSelection.java @@ -0,0 +1,35 @@ +package fr.uha.graphics.shapes; + +import java.awt.Point; +import java.awt.Rectangle; + +public class SSelection extends SRectangle { + + public SSelection(){ + super(new Point(0, 0), 0, 0); + } + + public SSelection(Point loc, int width, int length) { + super(loc, width, length); + } + + public void resize(int width, int height){ + this.getRect().setSize(width, height); + } + + @Override + public String toString() { + Rectangle rect = this.getRect(); + return "SSelection [x=" + rect.x + " y=" + rect.y + " height=" + rect.height + " width=" + rect.width + "]"; + } + + @Override + public String cssShape() { + return ""; + } + + @Override + public String htmlShape() { + return ""; + } +} diff --git a/src/fr/uha/graphics/shapes/SText.java b/src/fr/uha/graphics/shapes/SText.java new file mode 100755 index 0000000..795f0a0 --- /dev/null +++ b/src/fr/uha/graphics/shapes/SText.java @@ -0,0 +1,89 @@ +package fr.uha.graphics.shapes; + +import java.awt.Canvas; +import java.awt.Color; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Point; +import java.awt.Rectangle; + +import fr.uha.graphics.shapes.attributes.ColorAttributes; +import fr.uha.graphics.shapes.attributes.FontAttributes; + +public class SText extends Shape { + + private String text; + private Point loc; + + public SText(Point loc, String string) { + this.text = string; + this.loc = loc; + } + + public String getText() { + return this.text; + } + + @Override + public Point getLoc() { + return this.loc; + } + + @Override + public void setLoc(Point loc) { + this.loc = loc; + } + + @Override + public void translate(int dx, int dy) { + this.loc.translate(dx, dy); + } + + @Override + public Rectangle getBounds() { + FontAttributes attrs = (FontAttributes) this.getAttributes(FontAttributes.ID); + Canvas can = new Canvas(); + FontMetrics fontMetrics = can.getFontMetrics(attrs.font); + + int w = fontMetrics.stringWidth(this.text); + int h = attrs.font.getSize(); + return new Rectangle(loc.x, loc.y - h, w, h); + } + + @Override + public void accept(ShapeVisitor sv) { + sv.visitText(this); + } + + @Override + public String htmlShape() { + return "
"+getText()+"
"; + } + + @Override + public String cssShape() { + Rectangle bounds = this.getBounds(); + FontAttributes fontAttrs = (FontAttributes) this.getAttributes(FontAttributes.ID); + String hexFontColor = String.format("#%02x%02x%02x", + fontAttrs.fontColor.getRed(), + fontAttrs.fontColor.getGreen(), + fontAttrs.fontColor.getBlue()); + Font font = fontAttrs.font; + + StringBuilder strBuilder = new StringBuilder(".text" + this.hashCode() + "{ "); + strBuilder.append("position: absolute;"); + strBuilder.append("top: " + this.loc.y + "px;"); + strBuilder.append("left: " + this.loc.x + "px;"); + strBuilder.append("width: " + bounds.width + "px;"); + strBuilder.append("height: " + bounds.height + "px;"); + strBuilder.append("font-family: \"" + font.getName() + "\";"); + strBuilder.append("font-size: " + font.getSize() + "px;"); + strBuilder.append("color: " + hexFontColor +";"); + if (font.isBold()) strBuilder.append("font-weight: bold;"); + if (font.isItalic()) strBuilder.append("font-style: italic;"); + strBuilder.append(this.attributesCss()); + strBuilder.append(" }"); + return strBuilder.toString(); + } + +} diff --git a/src/fr/uha/graphics/shapes/STriangle.java b/src/fr/uha/graphics/shapes/STriangle.java new file mode 100644 index 0000000..4ccac73 --- /dev/null +++ b/src/fr/uha/graphics/shapes/STriangle.java @@ -0,0 +1,80 @@ +package fr.uha.graphics.shapes; + +import java.awt.Point; +import java.awt.Rectangle; + +import fr.uha.graphics.shapes.attributes.ColorAttributes; + +public class STriangle extends Shape { + + private static final int DEFAULT_SIZE = 1; + private Point loc; + private int size; + + public STriangle(){ + this.size = DEFAULT_SIZE; + this.loc = new Point(); + } + + public STriangle(Point loc, int size){ + this.loc = loc; + this.size = size; + } + + @Override + public void translate(int dx, int dy) { + this.loc.translate(dx, dy); + } + + @Override + public Point getLoc() { + return this.loc; + } + + @Override + public void setLoc(Point p) { + this.loc = p; + } + + public int getSize(){ + return this.size; + } + + @Override + public Rectangle getBounds() { + return new Rectangle(loc.x, loc.y, size, size); + } + + @Override + public void accept(ShapeVisitor sv) { + sv.visitTriangle(this); + } + + @Override + public String htmlShape() { + return "
"; + } + + @Override + public String cssShape() { + ColorAttributes colAttrs = (ColorAttributes) this.getAttributes(ColorAttributes.ID); + String colorString = String.format("#%02x%02x%02x", + colAttrs.filledColor.getRed(), + colAttrs.filledColor.getGreen(), + colAttrs.filledColor.getBlue()); + StringBuilder strBuilder = new StringBuilder(".triangle" + this.hashCode() + "{ "); + strBuilder.append("position: absolute;"); + strBuilder.append("top: " + this.loc.y + "px;"); + strBuilder.append("left: " + this.loc.x + "px;"); + strBuilder.append("width: 0px;"); + strBuilder.append("height: 0px;"); + strBuilder.append("border: 0 solid transparent;"); + strBuilder.append("border-left-width: " + Math.ceil(this.size/1.72) + "px;"); + strBuilder.append("border-right-width: " + Math.ceil(this.size/1.72) + "px;"); + strBuilder.append("border-bottom: " + this.size + "px solid " + colorString + ";"); + strBuilder.append("}"); + + return strBuilder.toString(); + } + +} diff --git a/src/fr/uha/graphics/shapes/Shape.java b/src/fr/uha/graphics/shapes/Shape.java new file mode 100755 index 0000000..54749ec --- /dev/null +++ b/src/fr/uha/graphics/shapes/Shape.java @@ -0,0 +1,63 @@ +package fr.uha.graphics.shapes; + +import java.awt.Point; +import java.awt.Rectangle; +import java.util.Map; +import java.util.TreeMap; +import java.util.logging.Level; +import java.util.logging.Logger; + +import fr.uha.graphics.shapes.attributes.Attributes; +import fr.uha.graphics.shapes.attributes.ColorAttributes; + +public abstract class Shape { + + private static final Logger LOGGER = Logger.getLogger(SCollection.class.getName()); + private Map attributes = new TreeMap(); + + public void addAttributes(Attributes attrs) { + attributes.put(attrs.getId(), attrs); + } + + public Attributes getAttributes(String str) { + return attributes.get(str); + } + + public String attributesCss(){ + + ColorAttributes colAttrs = (ColorAttributes) this.getAttributes(ColorAttributes.ID); + String strokedColor = "#ffffff"; + String filledColor = "#ffffff"; + if (colAttrs.filledColor != null){ + filledColor = String.format("#%02x%02x%02x", colAttrs.filledColor.getRed(), colAttrs.filledColor.getGreen(), colAttrs.filledColor.getBlue()); + } + if (colAttrs.strokedColor != null){ + strokedColor = String.format("#%02x%02x%02x", colAttrs.strokedColor.getRed(), colAttrs.strokedColor.getGreen(), colAttrs.strokedColor.getBlue()); + } + + if(colAttrs.stroked && colAttrs.filled){ + return "background: " + filledColor + ";border:1px solid " + strokedColor + ";"; + } + if (colAttrs.stroked){ + return "background:#ffffff;border:1px solid "+strokedColor+";"; + } + if (colAttrs.filled) { + return "background: "+filledColor+";"; + } + return null; + } + + public abstract void translate(int dx, int dy); + + public abstract Point getLoc(); + + public abstract void setLoc(Point p); + + public abstract Rectangle getBounds(); + + public abstract void accept(ShapeVisitor sv); + + public abstract String htmlShape(); + + public abstract String cssShape(); +} diff --git a/src/fr/uha/graphics/shapes/ShapeVisitor.java b/src/fr/uha/graphics/shapes/ShapeVisitor.java new file mode 100755 index 0000000..02abdbe --- /dev/null +++ b/src/fr/uha/graphics/shapes/ShapeVisitor.java @@ -0,0 +1,15 @@ +package fr.uha.graphics.shapes; + +public interface ShapeVisitor { + public void visitRectangle(SRectangle rect); + + public void visitCircle(SCircle circle); + + public void visitText(SText text); + + public void visitCollection(SCollection col); + + public void visitTriangle(STriangle sTriangle); + + public void visitSelection(SSelection sel); +} diff --git a/src/fr/uha/graphics/shapes/attributes/Attributes.java b/src/fr/uha/graphics/shapes/attributes/Attributes.java new file mode 100755 index 0000000..b2f93de --- /dev/null +++ b/src/fr/uha/graphics/shapes/attributes/Attributes.java @@ -0,0 +1,5 @@ +package fr.uha.graphics.shapes.attributes; + +public abstract class Attributes { + public abstract String getId(); +} diff --git a/src/fr/uha/graphics/shapes/attributes/ColorAttributes.java b/src/fr/uha/graphics/shapes/attributes/ColorAttributes.java new file mode 100755 index 0000000..c42edec --- /dev/null +++ b/src/fr/uha/graphics/shapes/attributes/ColorAttributes.java @@ -0,0 +1,48 @@ +package fr.uha.graphics.shapes.attributes; + +import java.awt.Color; + +public class ColorAttributes extends Attributes { + + public static final String ID = "colors"; + + public boolean filled; + public boolean stroked; + public Color strokedColor; + public Color filledColor; + + public ColorAttributes(boolean filled, boolean stroked, Color filledColor, Color strokedColor) { + this.filled = filled; + this.stroked = stroked; + this.strokedColor = strokedColor; + this.filledColor = filledColor; + } + + public ColorAttributes(ColorAttributes colAttrs){ + // Copy constructor. + this.filled = colAttrs.filled; + this.stroked = colAttrs.stroked; + this.strokedColor = colAttrs.strokedColor; + this.filledColor = colAttrs.filledColor; + } + + public ColorAttributes() { + // Constructor for color attributes with default values + this.filled = false; + this.stroked = true; + this.strokedColor = Color.BLACK; + this.filledColor = Color.BLACK; + } + + @Override + public String getId() { + return ID; + } + + @Override + public String toString() { + return "ColorAttributes [filled=" + filled + ", stroked=" + stroked + ", strokedColor=" + strokedColor + + ", filledColor=" + filledColor + "]"; + } + +} diff --git a/src/fr/uha/graphics/shapes/attributes/FontAttributes.java b/src/fr/uha/graphics/shapes/attributes/FontAttributes.java new file mode 100755 index 0000000..ffee35a --- /dev/null +++ b/src/fr/uha/graphics/shapes/attributes/FontAttributes.java @@ -0,0 +1,34 @@ +package fr.uha.graphics.shapes.attributes; + +import java.awt.Color; +import java.awt.Font; +import java.awt.Rectangle; + +public class FontAttributes extends Attributes { + public static final String ID = "font"; + + public Font font; + public Color fontColor; + + public FontAttributes(Font font, Color fontColor) { + this.font = font; + this.fontColor = fontColor; + } + + public FontAttributes() { + // Constructor with default font attributes values. + this.font = new Font("TimesRoman", Font.PLAIN, 18); + this.fontColor = Color.BLACK; + } + + @Override + public String toString() { + return "FontAttributes [font=" + font + ", fontColor=" + fontColor + "]"; + } + + @Override + public String getId() { + return ID; + } + +} diff --git a/src/fr/uha/graphics/shapes/attributes/SelectionAttributes.java b/src/fr/uha/graphics/shapes/attributes/SelectionAttributes.java new file mode 100755 index 0000000..0165ed3 --- /dev/null +++ b/src/fr/uha/graphics/shapes/attributes/SelectionAttributes.java @@ -0,0 +1,33 @@ +package fr.uha.graphics.shapes.attributes; + +public class SelectionAttributes extends Attributes { + public static final String ID = "selection"; + + private boolean selected; + + public SelectionAttributes() { + this.selected = false; + } + + public void select() { + selected = true; + } + + public void unselect() { + selected = false; + } + + public void toggleSelection() { + selected = !selected; + } + + public boolean isSelected() { + return this.selected; + } + + @Override + public String getId() { + return ID; + } + +} diff --git a/src/fr/uha/graphics/shapes/ui/.DS_Store b/src/fr/uha/graphics/shapes/ui/.DS_Store new file mode 100755 index 0000000000000000000000000000000000000000..e307fbc6527d82b4f8b45f7d8ed9c0216cf16673 GIT binary patch literal 6148 zcmeHKO-lno41J@E6nZIo@!(-DUPb@GQrd$z!9QSY5h}$6QP2C^{A2oF62;>7sE8zx zyv!t-nSHSH0iaBuR~Ntpz=$d=at1`*gQ2}h78V<$!z0dcj|E-^2KtL#TKgDttgyxt zzOH|9x#@0~n{LSr(Q`#TdNZN7vugct*G1Ji@OpB3XxRs}jaTosmYF6QNCuLDWFQ&% zSq6A!OGabIw8=m+kPLh>p#7mzg>7K(Xj=!3uFr}$LJ56cmW4I24eT8mp%gDAdTEI# zM)7j?*T`!Fdq*!vv6(qe%>40qDK5{?GZ#3_kL=OR|*= zBm@79fzr&bXH$MuoUPwJPiJkV-cTjV>*Y}BZ(Rb|&^~f(L62AY%xeRCM~$L>D<|ef Mzz9i`4EzEE?*r6BH2?qr literal 0 HcmV?d00001 diff --git a/src/fr/uha/graphics/shapes/ui/Editor.java b/src/fr/uha/graphics/shapes/ui/Editor.java new file mode 100755 index 0000000..263cdb0 --- /dev/null +++ b/src/fr/uha/graphics/shapes/ui/Editor.java @@ -0,0 +1,210 @@ +package fr.uha.graphics.shapes.ui; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.Point; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.IOException; +import java.util.logging.FileHandler; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.logging.SimpleFormatter; + +import javax.swing.JCheckBoxMenuItem; +import javax.swing.JFrame; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; +import javax.swing.JOptionPane; + +import fr.uha.graphics.shapes.SCircle; +import fr.uha.graphics.shapes.SCollection; +import fr.uha.graphics.shapes.SRectangle; +import fr.uha.graphics.shapes.SSelection; +import fr.uha.graphics.shapes.SText; +import fr.uha.graphics.shapes.STriangle; +import fr.uha.graphics.shapes.attributes.ColorAttributes; +import fr.uha.graphics.shapes.attributes.FontAttributes; +import fr.uha.graphics.shapes.attributes.SelectionAttributes; +import fr.uha.graphics.shapes.ui.menu.MenuAddListener; +import fr.uha.graphics.shapes.ui.menu.MenuEditListener; + +public class Editor extends JFrame { + private static final Logger LOGGER = Logger.getLogger(Editor.class.getName()); + private static FileHandler fh = null; + public static final Dimension WIN_SIZE = new Dimension(800, 600); + + private ShapesView sview; + private SCollection model; + private JMenuBar menubar; + + public Editor() { + super("Shapes Editor"); + + this.addWindowListener(new java.awt.event.WindowAdapter() { + @Override + public void windowClosing(java.awt.event.WindowEvent evt) { + System.exit(0); + } + }); + + this.buildModel(); + + this.sview = new ShapesView(this.model); + this.sview.setPreferredSize(WIN_SIZE); + this.getContentPane().add(this.sview, java.awt.BorderLayout.CENTER); + this.buildMenu(); + } + + private static void initLogger() { + try { + fh = new FileHandler("Shapes.log", false); + } catch (SecurityException | IOException e) { + e.printStackTrace(); + } + Logger l = Logger.getLogger(""); + fh.setFormatter(new SimpleFormatter()); + l.addHandler(fh); + l.setLevel(Level.INFO); + } + + private void buildModel() { + this.model = new SCollection(); + this.model.addAttributes(new SelectionAttributes()); + + SSelection sel=new SSelection(new Point (0,0),0,0); + sel.addAttributes(new ColorAttributes(false, true, Color.BLACK, Color.BLACK)); + this.model.add(sel); + + SRectangle r = new SRectangle(new Point(10, 10), 40, 60); + r.addAttributes(new ColorAttributes(true, true, Color.BLUE, Color.BLACK)); + r.addAttributes(new SelectionAttributes()); + this.model.add(r); + + SCircle c = new SCircle(new Point(100, 100), 30); + c.addAttributes(new ColorAttributes(false, true, Color.RED, Color.RED)); + c.addAttributes(new SelectionAttributes()); + this.model.add(c); + + SText t = new SText(new Point(150, 150), "hello"); + t.addAttributes(new ColorAttributes(true, false, Color.YELLOW, Color.BLUE)); + t.addAttributes(new FontAttributes(new Font("Arial", Font.BOLD, 30), Color.BLUE)); + t.addAttributes(new SelectionAttributes()); + this.model.add(t); + + SCollection sc = new SCollection(); + sc.addAttributes(new SelectionAttributes()); + r = new SRectangle(new Point(20, 30), 60, 60); + r.addAttributes(new ColorAttributes(true, false, Color.MAGENTA, Color.BLUE)); + r.addAttributes(new SelectionAttributes()); + sc.add(r); + + c = new SCircle(new Point(150, 100), 40); + c.addAttributes(new ColorAttributes(false, true, Color.BLUE, Color.DARK_GRAY)); + c.addAttributes(new SelectionAttributes()); + sc.add(c); + this.model.add(sc); + + STriangle tri = new STriangle(new Point(200, 200), 50); + tri.addAttributes(new ColorAttributes(true, true, Color.YELLOW, Color.BLACK)); + tri.addAttributes(new SelectionAttributes()); + this.model.add(tri); + } + + private void buildMenu(){ + this.menubar = new JMenuBar(); + + // Add menu + JMenu menuFile = new JMenu("File"); + JMenuItem addRectItem = new JMenuItem("Add SRectangle"); + JMenuItem addCircleItem = new JMenuItem("Add SCircle"); + JMenuItem addTriItem = new JMenuItem("Add STriangle"); + JMenuItem addTextItem = new JMenuItem("Add SText"); + JMenuItem htmlExportItem = new JMenuItem("Export to HTML"); + JMenuItem exitItem = new JMenuItem("Exit"); + addRectItem.addActionListener(new MenuAddListener("SRectangle", model, sview)); + addCircleItem.addActionListener(new MenuAddListener("SCircle", model, sview)); + addTriItem.addActionListener(new MenuAddListener("STriangle", model, sview)); + addTextItem.addActionListener(new MenuAddListener("SText", model, sview)); + htmlExportItem.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent arg0) { + try { + ((ShapesController) sview.getController()).generateHtml(); + JOptionPane.showMessageDialog(null, "HTML/CSS generated successfully !", "Success", + JOptionPane.INFORMATION_MESSAGE); + } catch (Exception e) { + LOGGER.log(Level.SEVERE, e.getMessage()); + JOptionPane.showMessageDialog(null, "Error while generating the HTML/CSS. See log for more details", + "Error", JOptionPane.ERROR_MESSAGE); + } + } + }); + exitItem.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent arg0) { + System.exit(0); + } + }); + menuFile.add(addRectItem); + menuFile.add(addCircleItem); + menuFile.add(addTriItem); + menuFile.add(addTextItem); + menuFile.addSeparator(); + menuFile.add(htmlExportItem); + menuFile.add(exitItem); + + // Edit menu + MenuEditListener editListener = new MenuEditListener(model, sview, sview.getController()); + JMenu menuEdit = new JMenu("Edit"); + JMenuItem editColor = new JMenuItem("Change color"); + JMenuItem editBorderColor = new JMenuItem("Change border color"); + JMenuItem deleteItem = new JMenuItem("Delete"); + JMenuItem undoItem = new JMenuItem("Undo"); + JCheckBoxMenuItem editFill = new JCheckBoxMenuItem("Fill Shape"); + JCheckBoxMenuItem editBorder = new JCheckBoxMenuItem("Draw border"); + editColor.addActionListener(editListener); + editBorderColor.addActionListener(editListener); + deleteItem.addActionListener(editListener); + undoItem.addActionListener(editListener); + editFill.addActionListener(editListener); + editBorder.addActionListener(editListener); + + menuEdit.add(editColor); + menuEdit.add(editBorderColor); + menuEdit.add(deleteItem); + menuEdit.add(undoItem); + menuEdit.addSeparator(); + menuEdit.add(editBorder); + menuEdit.add(editFill); + + // About + JMenu helpMenu = new JMenu("Help"); + JMenuItem aboutItem = new JMenuItem("About"); + aboutItem.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent arg0) { + JOptionPane.showMessageDialog(null, "This project was created by Alexandre Colicchio and Thibaud Gasser", "About this project", + JOptionPane.INFORMATION_MESSAGE); + } + }); + helpMenu.add(aboutItem); + + menubar.add(menuFile); + menubar.add(menuEdit); + menubar.add(helpMenu); + this.setJMenuBar(this.menubar); + } + + public static void main(String[] args) { + Editor.initLogger(); + Editor self = new Editor(); + self.pack(); + self.sview.requestFocusInWindow(); + self.setVisible(true); + + } +} diff --git a/src/fr/uha/graphics/shapes/ui/ShapeDraftman.java b/src/fr/uha/graphics/shapes/ui/ShapeDraftman.java new file mode 100755 index 0000000..13310bb --- /dev/null +++ b/src/fr/uha/graphics/shapes/ui/ShapeDraftman.java @@ -0,0 +1,161 @@ +package fr.uha.graphics.shapes.ui; + +import java.awt.Color; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Point; +import java.awt.Rectangle; +import java.util.Iterator; +import java.util.logging.Logger; + +import fr.uha.graphics.shapes.SCircle; +import fr.uha.graphics.shapes.SCollection; +import fr.uha.graphics.shapes.SRectangle; +import fr.uha.graphics.shapes.SSelection; +import fr.uha.graphics.shapes.SText; +import fr.uha.graphics.shapes.STriangle; +import fr.uha.graphics.shapes.Shape; +import fr.uha.graphics.shapes.ShapeVisitor; +import fr.uha.graphics.shapes.attributes.ColorAttributes; +import fr.uha.graphics.shapes.attributes.FontAttributes; +import fr.uha.graphics.shapes.attributes.SelectionAttributes; + +public class ShapeDraftman implements ShapeVisitor { + + private static final Logger LOGGER = Logger.getLogger(ShapeDraftman.class.getName()); + + // Default attributes + private static final ColorAttributes DEFAULT_COLOR_ATTRIBUTES = new ColorAttributes(false, true, Color.BLACK, Color.BLACK); + + private Graphics2D graph; + + public ShapeDraftman(Graphics graph) { + this.graph = (Graphics2D) graph; + } + + @Override + public void visitRectangle(SRectangle rect) { + Rectangle r = rect.getRect(); + ColorAttributes colAttrs = (ColorAttributes) rect.getAttributes(ColorAttributes.ID); + + if (colAttrs == null){ + colAttrs = DEFAULT_COLOR_ATTRIBUTES; + } + if (colAttrs.filled) { + this.graph.setColor(colAttrs.filledColor); + this.graph.fillRect(r.x, r.y, r.width, r.height); + } + if (colAttrs.stroked) { + this.graph.setColor(colAttrs.strokedColor); + this.graph.drawRect(r.x, r.y, r.width, r.height); + } + drawHandlerIfSelected(rect); + } + + @Override + public void visitCircle(SCircle circle) { + ColorAttributes colAttrs = (ColorAttributes) circle.getAttributes(ColorAttributes.ID); + + if (colAttrs == null) { + colAttrs = DEFAULT_COLOR_ATTRIBUTES; + } + if (colAttrs.filled) { + this.graph.setColor(colAttrs.filledColor); + this.graph.fillOval(circle.getLoc().x, circle.getLoc().y, circle.getRadius(), circle.getRadius()); + } + if (colAttrs.stroked) this.graph.setColor(colAttrs.strokedColor); + this.graph.drawOval(circle.getLoc().x, circle.getLoc().y, circle.getRadius(), circle.getRadius()); + + drawHandlerIfSelected(circle); +} + + @Override + public void visitText(SText text) { + Point loc = text.getLoc(); + Rectangle bounds = text.getBounds(); + // Fetch SText attributes + ColorAttributes colAttrs = (ColorAttributes) text.getAttributes(ColorAttributes.ID); + FontAttributes fontAttrs = (FontAttributes) text.getAttributes(FontAttributes.ID); + + if (colAttrs == null){ + colAttrs = DEFAULT_COLOR_ATTRIBUTES; + } + if (colAttrs.filled) { + this.graph.setColor(colAttrs.filledColor); + // The reference point for Rectangle is the upper-left corner, + // whereas it is the bottom-left corner for Font.drawString(). + this.graph.fillRect(loc.x, loc.y - bounds.height, bounds.width, bounds.height); + } + if (colAttrs.stroked){ + this.graph.setColor(colAttrs.strokedColor); + this.graph.drawRect(loc.x, loc.y - bounds.height, bounds.width, bounds.height); + } + this.graph.setFont(fontAttrs.font); + this.graph.setPaint(fontAttrs.fontColor); + this.graph.drawString(text.getText(), loc.x, loc.y); + + drawHandlerIfSelected(text); + } + + @Override + public void visitCollection(SCollection col) { + for (Iterator it = col.getIterator(); it.hasNext();) { + Shape current = it.next(); + current.accept(this); + } + + drawHandlerIfSelected(col); + } + + public void visitTriangle(STriangle tri){ + Point loc = tri.getLoc(); + int size = tri.getSize(); + ColorAttributes colAttrs = (ColorAttributes) tri.getAttributes(ColorAttributes.ID); + + if (colAttrs == null){ + colAttrs = DEFAULT_COLOR_ATTRIBUTES; + } + if (colAttrs.filled) { + this.graph.setColor(colAttrs.filledColor); + this.graph.fillPolygon(new int[]{loc.x, loc.x+(size/2), loc.x + size}, + new int[]{loc.y+size, loc.y, loc.y+size}, + 3); + } + if (colAttrs.stroked) this.graph.setColor(colAttrs.strokedColor); + this.graph.drawPolygon(new int[]{loc.x, loc.x+(size/2), loc.x + size}, + new int[]{loc.y+size, loc.y, loc.y+size}, + 3); + + drawHandlerIfSelected(tri); + } + + @Override + public void visitSelection(SSelection sel) { + Rectangle r = sel.getRect(); + ColorAttributes attrs = (ColorAttributes) sel.getAttributes(ColorAttributes.ID); + + if (attrs == null) attrs = DEFAULT_COLOR_ATTRIBUTES; + this.graph.drawRect(r.x, r.y, r.width, r.height); + } + + /* + * Draw handlers on all selected shapes. + */ + private void drawHandlerIfSelected(Shape s){ + SelectionAttributes selAttrs = (SelectionAttributes) s.getAttributes(SelectionAttributes.ID); + if ((selAttrs != null)&&(selAttrs.isSelected())){ + Rectangle bounds = s.getBounds(); + drawHandler(bounds); + } + } + + public void drawHandler(Rectangle bounds) { + this.graph.setColor(Color.RED); + this.graph.drawRect(bounds.x - 5, bounds.y - 5, 5, 5); + this.graph.drawRect(bounds.x + bounds.width, bounds.y + bounds.height, 5, 5); + } + + public void setGraphics(Graphics g) { + this.graph = (Graphics2D) g; + } +} diff --git a/src/fr/uha/graphics/shapes/ui/ShapesController.java b/src/fr/uha/graphics/shapes/ui/ShapesController.java new file mode 100644 index 0000000..758669e --- /dev/null +++ b/src/fr/uha/graphics/shapes/ui/ShapesController.java @@ -0,0 +1,321 @@ +package fr.uha.graphics.shapes.ui; + +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.event.KeyEvent; +import java.awt.event.MouseEvent; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.ListIterator; +import java.util.logging.Level; +import java.util.logging.Logger; + +import fr.uha.graphics.shapes.SCircle; +import fr.uha.graphics.shapes.SCollection; +import fr.uha.graphics.shapes.SRectangle; +import fr.uha.graphics.shapes.SSelection; +import fr.uha.graphics.shapes.SText; +import fr.uha.graphics.shapes.STriangle; +import fr.uha.graphics.shapes.Shape; +import fr.uha.graphics.shapes.attributes.ColorAttributes; +import fr.uha.graphics.shapes.attributes.FontAttributes; +import fr.uha.graphics.shapes.attributes.SelectionAttributes; +import fr.uha.graphics.ui.Controller; + +public class ShapesController extends Controller { + + private static final Logger LOGGER = Logger.getLogger(ShapesController.class.getName()); + private boolean shiftDown; + private Point locClicked; + private SSelection sel; + private List copyMem = new ArrayList(); + private List delMem = new ArrayList(); + + + public ShapesController(Shape model) { + super(model); + + this.locClicked = new Point(); + this.shiftDown = false; + this.sel = new SSelection(); + } + + @Override + public Object getModel() { + return super.getModel(); + } + + @Override + public void mousePressed(MouseEvent e) { + super.mousePressed(e); + this.locClicked = e.getPoint(); + Shape target = getTarget(); + + if (!shiftDown()){ + unselectAll(); + } + + if (target != null){ + SelectionAttributes selAttrs = (SelectionAttributes) target.getAttributes(SelectionAttributes.ID); + if (selAttrs != null){ + selAttrs.toggleSelection(); + } + } + getView().repaint(); + } + + @Override + public void mouseClicked(MouseEvent e) { + super.mouseClicked(e); + } + + @Override + public void mouseReleased(MouseEvent e) { + SSelection currentSSelection = this.sel; + for (Iterator it = ((SCollection) this.getModel()).getIterator(); it.hasNext();) { + Shape current = it.next(); + + if (this.sel.getBounds().contains(current.getBounds())) { + select(current); + getView().repaint(); + } + if (current instanceof SSelection) current = currentSSelection; + } + currentSSelection.setLoc(new Point(0, 0)); + currentSSelection.resize(0, 0); + this.sel = currentSSelection; + getView().repaint(); + } + + @Override + public void mouseDragged(MouseEvent evt) { + super.mouseDragged(evt); + boolean anyShapeSelected = isAnyShapeSelected(); + + for (Iterator it = ((SCollection) this.getModel()).getIterator(); it.hasNext();) { + Shape current = it.next(); + + if ((!anyShapeSelected) && (current instanceof SSelection)) { + this.sel = (SSelection) current; + this.sel.setLoc(this.locClicked); + this.sel.resize(evt.getX()-this.locClicked.x, evt.getY()-this.locClicked.y); + getView().repaint(); + } + // Translate all selected shapes. + if(isSelected(current)){ + int dx = evt.getPoint().x - current.getLoc().x; + int dy = evt.getPoint().y - current.getLoc().y; + translateSelected(dx, dy); + } + } + } + + @Override + public void keyPressed(KeyEvent evt) { + super.keyPressed(evt); + switch (evt.getKeyCode()) { + case KeyEvent.VK_SHIFT: + shiftDown = true; + break; + case KeyEvent.VK_DELETE: + deleteSelected(); + break; + case KeyEvent.VK_Z: + undo(); + break; + case KeyEvent.VK_C: + copy(); + break; + case KeyEvent.VK_V: + paste(); + break; + case KeyEvent.VK_H: + LOGGER.info("HTML/CSS generated"); + try { + generateHtml(); + } catch (IOException e) { + LOGGER.log(Level.SEVERE, e.getMessage()); + } + break; + default: + break; + } + } + + @Override + public void keyReleased(KeyEvent evt) { + super.keyReleased(evt); + switch (evt.getKeyCode()) { + case KeyEvent.VK_SHIFT: + shiftDown = false; + break; + } + } + + public Shape getTarget() { + SCollection model = (SCollection) getModel(); + Iterator it = model.getIterator(); + while (it.hasNext()) { + Shape current = it.next(); + if (current.getBounds().contains(this.locClicked)) { + LOGGER.log(Level.INFO, "Shape selected : {0}", current); + return current; + } + } + return null; + } + + public void translateSelected(int dx, int dy) { + for (Iterator it = ((SCollection) this.getModel()).getIterator(); it.hasNext();) { + Shape current = it.next(); + if (isSelected(current)) current.translate(dx, dy); + } + getView().repaint(); + } + + public void deleteSelected(){ + ArrayList toDelete = new ArrayList(); + for (Iterator it = ((SCollection) this.getModel()).getIterator(); it.hasNext();) { + Shape current = it.next(); + if(isSelected(current)){ + this.delMem.add(current); + toDelete.add(current); + } + } + for (Shape current: toDelete){ + LOGGER.log(Level.INFO, "Removing shape {0}", current); + ((SCollection)this.getModel()).remove(current); + } + unselectAll(); // unselectAll() takes care of the graphical update (repaint). + } + + public void unselectAll() { + for (Iterator it = ((SCollection) this.getModel()).getIterator(); it.hasNext();) { + Shape current = it.next(); + unselect(current); + } + getView().repaint(); + } + + public void generateHtml() throws IOException { + PrintWriter index = new PrintWriter("index.html", "UTF-8"); + PrintWriter style = new PrintWriter("style.css", "UTF-8"); + + index.println(""); + index.println(""); + index.println(""); + index.println(""); + index.println(""); + index.println("TP Shape COLICCHIO et GASSER"); + index.println(""); + index.println(""); + + for (Iterator it = ((SCollection) this.getModel()).getIterator(); it.hasNext();) { + Shape current = it.next(); + index.println(current.htmlShape()); + } + index.flush(); + index.println("
"); + index.println("

2017 Crée par Alexandre COLICCHIO et Thibaud GASSER - Site généré automatiquement dans le cadre de notre TP Shape

"); + index.println("
"); + index.println(""); + index.println(""); + index.close(); + + style.println("footer{text-align:center;margin:auto;height:50px;position:fixed;bottom:0;font-weight:bold;}"); + + for (Iterator it = ((SCollection) this.getModel()).getIterator(); it.hasNext();) { + Shape current = it.next(); + style.println(current.cssShape()); + } + style.close(); + } + + public boolean shiftDown() { + return this.shiftDown; + } + + private boolean isAnyShapeSelected(){ + for (Iterator it = ((SCollection) this.getModel()).getIterator(); it.hasNext();) { + Shape current = it.next(); + if (isSelected(current)) return true; + } + return false; + } + + private boolean isSelected(Shape s) { + SelectionAttributes attrs = (SelectionAttributes) s.getAttributes(SelectionAttributes.ID); + if (attrs == null) return false; + return attrs.isSelected(); + } + + private int select(Shape s) { + LOGGER.log(Level.INFO, "Selecting {0}", s); + SelectionAttributes attrs = (SelectionAttributes) s.getAttributes(SelectionAttributes.ID); + // If this shape has no selection attributes + if (attrs == null) return -1; + attrs.select(); + return 0; + } + + private int unselect(Shape s) { + SelectionAttributes attrs = (SelectionAttributes) s.getAttributes(SelectionAttributes.ID); + // If this shape has no selection attributes + if (attrs == null) return -1; + attrs.unselect(); + return 0; + } + + public void undo(){ + ListIterator it = delMem.listIterator(); + while(it.hasNext()){ + Shape str = it.next(); + ((SCollection) getModel()).add(str); + } + delMem.clear(); + getView().repaint(); + } + + private void copy(){ + for (Iterator it = ((SCollection) this.getModel()).getIterator(); it.hasNext();) { + Shape current = it.next(); + if(isSelected(current)){ + copyMem.add(current); + } + } + } + + private void paste(){ + SCollection model = (SCollection) this.getModel(); + for (Iterator it = copyMem.iterator(); it.hasNext();) { + Shape current = (Shape) it.next(); + Shape s = cloneShape(current); + model.add(s); + } + copyMem.clear(); + getView().repaint(); + } + + private Shape cloneShape(Shape s){ + Rectangle bounds = s.getBounds(); + Shape newShape = null; + + if (s instanceof STriangle) { + newShape = new STriangle(new Point(), bounds.width); + } else if (s instanceof SRectangle) { + newShape = new SRectangle(new Point(), bounds.width, bounds.height); + } else if (s instanceof SCircle) { + newShape = new SCircle(new Point(), bounds.width); + } else if (s instanceof SText) { + System.out.println("Texte : " + ((SText) s).getText()); + newShape = new SText(new Point(0, bounds.height), ((SText) s).getText()); + newShape.addAttributes((FontAttributes) s.getAttributes(FontAttributes.ID)); + } + newShape.addAttributes(new SelectionAttributes()); + newShape.addAttributes(s.getAttributes(ColorAttributes.ID)); + return newShape; + } +} diff --git a/src/fr/uha/graphics/shapes/ui/ShapesView.java b/src/fr/uha/graphics/shapes/ui/ShapesView.java new file mode 100755 index 0000000..01fa84a --- /dev/null +++ b/src/fr/uha/graphics/shapes/ui/ShapesView.java @@ -0,0 +1,37 @@ +package fr.uha.graphics.shapes.ui; + +import java.awt.Graphics; +import java.util.logging.Level; +import java.util.logging.Logger; + +import fr.uha.graphics.shapes.Shape; +import fr.uha.graphics.ui.Controller; +import fr.uha.graphics.ui.View; + +public class ShapesView extends View { + + private static final Logger LOGGER = Logger.getLogger(ShapesView.class.getName()); + + private ShapeDraftman draftman; + + public ShapesView(Shape model) { + super(model); + LOGGER.log(Level.INFO, "ShapesView({0})", model); + } + + @Override + public void paintComponent(Graphics component) { + // Draw the default (blank) JPanel + super.paintComponent(component); + // LOGGER.log(Level.INFO, "Drawing component : {0}", component); + Shape model = (Shape) this.getModel(); + this.draftman = new ShapeDraftman(component); + model.accept(draftman); + } + + @Override + public Controller defaultController(Object model) { + return new ShapesController((Shape) this.getModel()); + } + +} diff --git a/src/fr/uha/graphics/shapes/ui/menu/MenuAddListener.java b/src/fr/uha/graphics/shapes/ui/menu/MenuAddListener.java new file mode 100644 index 0000000..4c7043c --- /dev/null +++ b/src/fr/uha/graphics/shapes/ui/menu/MenuAddListener.java @@ -0,0 +1,59 @@ +package fr.uha.graphics.shapes.ui.menu; + +import java.awt.Color; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import fr.uha.graphics.shapes.SCircle; +import fr.uha.graphics.shapes.SCollection; +import fr.uha.graphics.shapes.SRectangle; +import fr.uha.graphics.shapes.SText; +import fr.uha.graphics.shapes.STriangle; +import fr.uha.graphics.shapes.Shape; +import fr.uha.graphics.shapes.attributes.ColorAttributes; +import fr.uha.graphics.shapes.attributes.FontAttributes; +import fr.uha.graphics.shapes.attributes.SelectionAttributes; +import fr.uha.graphics.shapes.ui.ShapesView; + +public class MenuAddListener implements ActionListener { + private String shape; + private ShapesView view; + private SCollection model; + + public MenuAddListener(String shape, SCollection model, ShapesView view) { + this.shape = shape; + this.model = model; + this.view = view; + } + @Override + public void actionPerformed(ActionEvent e) { + Shape s; + Rectangle bounds = model.getBounds(); + // All new shapes will be in the center of the panel. + Point loc = new Point((int)bounds.getCenterX(), (int)bounds.getCenterY()); + + if (this.shape.equals("SRectangle")){ + s = new SRectangle(loc, 50, 50); + } else if (this.shape.equals("SCircle")){ + s = new SCircle(loc, 50); + } else if (this.shape.equals("STriangle")){ + s = new STriangle(loc, 50); + } else if (this.shape.equals("SText")){ + s = new SText(loc, "Lorem ipsum"); + s.addAttributes(new FontAttributes()); + } + else return; + + s.addAttributes(new SelectionAttributes()); + s.addAttributes(new ColorAttributes(true, false, randomColor(), null)); + model.add(s); + view.repaint(); + } + + private Color randomColor(){ + return new Color((int)(Math.random() * 0x1000000)); + } + +} diff --git a/src/fr/uha/graphics/shapes/ui/menu/MenuEditListener.java b/src/fr/uha/graphics/shapes/ui/menu/MenuEditListener.java new file mode 100644 index 0000000..a38c07a --- /dev/null +++ b/src/fr/uha/graphics/shapes/ui/menu/MenuEditListener.java @@ -0,0 +1,115 @@ +package fr.uha.graphics.shapes.ui.menu; + +import java.awt.Color; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.Iterator; +import java.util.logging.Logger; + +import javax.swing.JCheckBoxMenuItem; +import javax.swing.JColorChooser; + +import fr.uha.graphics.shapes.SCollection; +import fr.uha.graphics.shapes.Shape; +import fr.uha.graphics.shapes.attributes.ColorAttributes; +import fr.uha.graphics.shapes.attributes.SelectionAttributes; +import fr.uha.graphics.shapes.ui.ShapesController; +import fr.uha.graphics.shapes.ui.ShapesView; +import fr.uha.graphics.ui.Controller; + +public class MenuEditListener implements ActionListener { + private static final Logger LOGGER = Logger.getLogger(SCollection.class.getName()); + + private SCollection model; + private ShapesView view; + private ShapesController controller; + + public MenuEditListener(SCollection model, ShapesView view, Controller controller) { + this.model = model; + this.view = view; + this.controller = (ShapesController) controller; + } + + @Override + public void actionPerformed(ActionEvent e) { + Object source = e.getSource(); + if (e.getActionCommand().equals("Change color")){ + Color newColor = JColorChooser.showDialog(null, "Choose a color", Color.RED); + changeColor(newColor); + } else if (e.getActionCommand().equals("Change border color")){ + Color newColor = JColorChooser.showDialog(null, "Choose a color", Color.RED); + changeBorderColor(newColor); + } else if (e.getActionCommand().equals("Delete")) this.controller.deleteSelected(); + else if (e.getActionCommand().equals("Undo")) this.controller.undo(); + else if (source instanceof JCheckBoxMenuItem) { + JCheckBoxMenuItem item = (JCheckBoxMenuItem) source; + if (item.getText().equals("Draw border")) setBorder(item.isSelected()); + if (item.getText().equals("Fill Shape")) setShapeFilled(item.getState()); + } + view.repaint(); + } + + private Color randomColor(){ + return new Color((int)(Math.random() * 0x1000000)); + } + + private void changeColor(Color filledColor){ + for (Iterator it = model.getIterator(); it.hasNext();) { + Shape current = (Shape)it.next(); + SelectionAttributes selAttrs = (SelectionAttributes) current.getAttributes(SelectionAttributes.ID); + if ((selAttrs == null) || (! selAttrs.isSelected())) continue; + + ColorAttributes currentColAttrs = (ColorAttributes) current.getAttributes(ColorAttributes.ID); + if (currentColAttrs != null) { + current.addAttributes(new ColorAttributes(currentColAttrs.filled, currentColAttrs.stroked, filledColor, currentColAttrs.strokedColor)); + } else { + current.addAttributes(new ColorAttributes(true, true, filledColor, Color.BLACK)); + } + } + } + + private void changeBorderColor(Color strockedColor){ + for (Iterator it = model.getIterator(); it.hasNext();) { + Shape current = (Shape)it.next(); + SelectionAttributes selAttrs = (SelectionAttributes) current.getAttributes(SelectionAttributes.ID); + if ((selAttrs == null) || (! selAttrs.isSelected())) continue; + + ColorAttributes currentColAttrs = (ColorAttributes) current.getAttributes(ColorAttributes.ID); + if (currentColAttrs != null) { + current.addAttributes(new ColorAttributes(currentColAttrs.filled, currentColAttrs.stroked, currentColAttrs.filledColor, strockedColor)); + } else { + current.addAttributes(new ColorAttributes(true, true, Color.WHITE, strockedColor)); + } + } + } + + /* + * Change the state of the border of all selected shapes. + */ + private void setBorder(boolean state){ + for (Iterator it=model.getIterator(); it.hasNext();){ + Shape current = (Shape)it.next(); + SelectionAttributes selAttrs = (SelectionAttributes)current.getAttributes(SelectionAttributes.ID); + if ((selAttrs == null) || (! selAttrs.isSelected())) continue; + ColorAttributes colAttrs = (ColorAttributes) current.getAttributes(ColorAttributes.ID); + colAttrs.stroked = state; + current.addAttributes(new ColorAttributes(colAttrs)); + } + } + + /* + * Change the filled state for all selected shapes. + */ + private void setShapeFilled(boolean state){ + LOGGER.info("setShapeFilled(" + state + ")"); + for (Iterator it=model.getIterator(); it.hasNext();){ + Shape current = it.next(); + SelectionAttributes selAttrs = (SelectionAttributes)current.getAttributes(SelectionAttributes.ID); + if ((selAttrs == null) || (!selAttrs.isSelected())) continue; + ColorAttributes colAttrs = (ColorAttributes) current.getAttributes(ColorAttributes.ID); + colAttrs.filled = state; + current.addAttributes(new ColorAttributes(colAttrs)); + } + } + +} diff --git a/src/fr/uha/graphics/ui/.DS_Store b/src/fr/uha/graphics/ui/.DS_Store new file mode 100755 index 0000000000000000000000000000000000000000..ffd2a83cbdfdcdb666c92fa23dbb9f84100adcd3 GIT binary patch literal 6148 zcmeHKO-sW-5Pe&Nw0N-K#pC`0(SHzXJ$Mm8@Z`a^DpW!P#gA+Lnt#T#M{oM(gK9~O zco8WxVdiZ%^ODWmkl6*029GyKKp#MtF4*ZYtT4GQ-m;GO6vU+Wn4?C;;}-K)c69tl z1!V4aam;y};eoUEHGc=V#|TdtomTZ^T-9S{%4c#;-}_Kw>qquM6nl0AdF^m`rgaV4;bh0su`%QoS~4opsL8h&$>{9Qo>w|HhDJy7 z%}4SlC*PqYeLC--H65umj2H@p0?P_)*=b+u|H=CO|1v4gLV-|VqZCNR@M1XND|u~g vy`0qAOuwd!NnT^Pps=B(n7LAl_vvcv&(a{4j*TIEXt5Ab86t!Nf2zPIg_M9% literal 0 HcmV?d00001 diff --git a/src/fr/uha/graphics/ui/Controller.java b/src/fr/uha/graphics/ui/Controller.java new file mode 100755 index 0000000..9787210 --- /dev/null +++ b/src/fr/uha/graphics/ui/Controller.java @@ -0,0 +1,73 @@ +package fr.uha.graphics.ui; + +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.awt.event.MouseMotionListener; + +public class Controller implements MouseListener, MouseMotionListener, KeyListener { + protected Object model; + private View view; + + public Controller(Object newModel) { + model = newModel; + } + + public void setView(View view) { + this.view = view; + } + + final public View getView() { + return this.view; + } + + public void setModel(Object model) { + this.model = model; + } + + public Object getModel() { + return this.model; + } + + @Override + public void mousePressed(MouseEvent e) { + } + + @Override + public void mouseReleased(MouseEvent e) { + } + + @Override + public void mouseClicked(MouseEvent e) { + } + + @Override + public void mouseEntered(MouseEvent e) { + } + + @Override + public void mouseExited(MouseEvent e) { + } + + @Override + public void mouseMoved(MouseEvent evt) { + } + + @Override + public void mouseDragged(MouseEvent evt) { + } + + @Override + public void keyTyped(KeyEvent evt) { + } + + @Override + public void keyPressed(KeyEvent evt) { + } + + @Override + public void keyReleased(KeyEvent evt) { + } + +} diff --git a/src/fr/uha/graphics/ui/View.java b/src/fr/uha/graphics/ui/View.java new file mode 100755 index 0000000..c39052a --- /dev/null +++ b/src/fr/uha/graphics/ui/View.java @@ -0,0 +1,34 @@ +package fr.uha.graphics.ui; + +import javax.swing.JPanel; + +public abstract class View extends JPanel { + private Object model; + private Controller controller; + + public View(Object model) { + this.model = model; + this.controller = defaultController(model); + this.controller.setView(this); + this.addMouseListener(this.controller); + this.addMouseMotionListener(this.controller); + this.addKeyListener(this.controller); + } + + public void setModel(Object model) { + this.model = model; + this.controller.setModel(model); + } + + public Object getModel() { + return this.model; + } + + public Controller defaultController(Object model) { + return new Controller(model); + } + + final public Controller getController() { + return this.controller; + } +} diff --git a/style.css b/style.css new file mode 100644 index 0000000..0e6d916 --- /dev/null +++ b/style.css @@ -0,0 +1,8 @@ +footer{text-align:center;margin:auto;height:50px;position:fixed;bottom:0;font-weight:bold;} + +.rectangle813589267{ position:absolute;top:89px;left:95px;width:60px;height:60px;background: #999999;border:1px solid #000000; }.circle1577038754{ position: absolute;top:159px;left:225px;width:40px;height:40px;border-radius:20px;-webkit-border-radius:20px;-o-border-radius:20px;-moz-border-radius:20px;background: #999999;border:1px solid #000000; } +.triangle527292885{ position: absolute;top: 38px;left: 243px;width: 0px;height: 0px;border: 0 solid transparent;border-left-width: 30.0px;border-right-width: 30.0px;border-bottom: 50px solid #ecb4ee;} +.rectangle1045587243{ position:absolute;top:105px;left:319px;width:40px;height:60px;background: #0000ff;border:1px solid #000000; } +.circle2117079733{ position: absolute;top:42px;left:109px;width:30px;height:30px;border-radius:15px;-webkit-border-radius:15px;-o-border-radius:15px;-moz-border-radius:15px;background: #999999;border:1px solid #ff0000; } +.text997905906{ position: absolute;top: 139px;left: 179px;width: 69px;height: 30px;font-family: "Arial";font-size: 30px;color: #0000ff;font-weight: bold;background: #ecb4ee;border:1px solid #0000ff; } +.rectangle1033207963{ position:absolute;top:185px;left:299px;width:50px;height:50px;background: #ecb4ee;border:1px solid #ffffff; }