00001 namespace Grendel.Base {
00002 using System.Collections.Generic;
00003 using System.Diagnostics;
00004
00005 public class CompositeShape : BaseShape {
00006 List<IShape> subshapes;
00007
00008 public CompositeShape(Canvas canvas, IShape parentShape)
00009 : base(canvas, parentShape) {
00010 subshapes = new List<IShape>();
00011 }
00012
00013 public CompositeShape(Canvas canvas)
00014 : this(canvas, null) {}
00015
00016 public void AddSubshape(IShape subshape, Position location) {
00017 if( !subshapes.Contains(subshape) ) {
00018 Debug.Assert(subshape.ParentShape == null, "Only subshape without parent is appendable to composite object");
00019 subshapes.Add(subshape);
00020 subshape.ParentShape = this;
00021 subshape.Location = location;
00022 }
00023 }
00024
00025 public override void Painting ()
00026 {
00027
00028 }
00029
00030 }
00031
00032
00033 public class CompositeInteractiveShape : BaseInteractiveShape {
00034 List<IShape> subshapes;
00035
00036 public CompositeInteractiveShape(Canvas canvas, IShape parentShape)
00037 : base(canvas, parentShape) {
00038 subshapes = new List<IShape>();
00039 }
00040
00041 public CompositeInteractiveShape(Canvas canvas)
00042 : this(canvas, null) {}
00043
00044 public void AddSubshape(IShape subshape, Position location) {
00045 if( !subshapes.Contains(subshape) ) {
00046 Debug.Assert(subshape.ParentShape == null, "Only subshape without parent is appendable to composite object");
00047 subshapes.Add(subshape);
00048 subshape.ParentShape = this;
00049 subshape.Location = location;
00050 }
00051 }
00052
00053 public void AddSubshape(IInteractiveShape subshape, Position location, bool deactivate) {
00054 AddSubshape(subshape, location);
00055 if(deactivate)
00056 subshape.IsActive = false;
00057
00058 }
00059
00060 private Parallelogram Wrapper() {
00061 if (subshapes.Count == 0)
00062 return Parallelogram.FromSimpleRectangle(Position.Origin, Position.Origin);
00063
00064 List<Position> pos = new List<Position>();
00065
00066 foreach(IShape shape in subshapes) {
00067 if(shape is IInteractiveShape) {
00068 IInteractiveShape ishape = shape as IInteractiveShape;
00069 Parallelogram p = Parallelogram.FromSimpleRectangle(ishape.LeftTopCorner,
00070 ishape.RightBottomCorner);
00071 WorldMatrix lt = new WorldMatrix(ishape.LocalTransformation);
00072 Parallelogram realp =
00073 p.Transform(lt.Translate(ishape.Location - Position.Origin));
00074
00075 pos.AddRange(realp.VertexEnumerator());
00076 }
00077 else
00078 pos.Add(shape.Location);
00079 }
00080
00081 Position l = pos[0];
00082 Position r = l;
00083 Position t = l;
00084 Position b = l;
00085
00086 foreach(Position p in pos) {
00087 if (p.IsLeftFrom(l))
00088 l = p;
00089 else if (p.IsRightFrom(r))
00090 r = p;
00091 if (p.IsAbove(t))
00092 t = p;
00093 else if (p.IsBelow(b))
00094 b = p;
00095 }
00096
00097 return Parallelogram.FromSimpleRectangle(new Position(l.X, t.Y), new Position(r.X, b.Y));
00098 }
00099
00100 public override void Painting ()
00101 {
00102 Parallelogram pg = Wrapper();
00103 for(int i=1; i<= 4; i++)
00104 Canvas.DrawLine(this, pg.Vertex(i-1), pg.Vertex(i%4), Color.Gray + Color.White);
00105
00106 }
00107
00108 public override Position LeftTopCorner {
00109 get {
00110 Parallelogram pg = Wrapper();
00111 return pg.Vertex(0);
00112 }
00113 }
00114
00115 public override Position RightBottomCorner {
00116 get {
00117 Parallelogram pg = Wrapper();
00118 return pg.Vertex(2);
00119 }
00120 }
00121
00122 public override void Interaction (MouseButtons button, Position location)
00123 {
00124
00125 }
00126
00127
00128
00129 }
00130
00131 }