Beispiel #1
0
		protected void Stop()
		{
			if ( !capture )
			{
				// we're not captured so ignore
				captureSpiro=null;
				return;
			}

			if ( current < 0 )
				// nothing selected so ignore
				return;

			// make sure old and new get invalidated
			Invalidate(CurrentSpiro);
			Invalidate(captureSpiro);

			// replace current with the modified copy
			spiros[current]=captureSpiro;
			captureSpiro.Selected=true;

			// re-enable the animation
			animateTimer.Enabled=true;

			// tidy up
			capture=false;
			captureSpiro=null;

			// ensure bounds are updated and re-locate button
			// (spiro may have changed size)
			RecalcBounds();
			UpdateFloatingButton();
		}
Beispiel #2
0
		/// Helper to invalidate a given spiro region
		private void Invalidate(SpiroInstance si)
		{
			Rectangle rc=CanvasToClient(si.BoundingRect);
			Invalidate(rc);
		}
Beispiel #3
0
		/// Add a new spiro provided
		public void AddSpiro(SpiroInstance si)
		{
			spiros.Add(si);
			si.CycleComplete+=new EventHandler(SpiroCycleComplete);
			RecalcBounds();
			Invalidate();
		}
Beispiel #4
0
		protected void Start(Point pt)
		{
			// hide the button
			spiroMenuButton.Enabled=false;
			spiroMenuButton.Visible=false;

			if ( spiroUnderCursor < 0 && current >= 0 )
			{
				// deselect all spiros
				// (click in region outside any spiro)
				CurrentSpiro.Selected=false;
				SetCurrentSpiro(-1);
				Invalidate();
				return;
			}

			pt=ClientToCanvas(pt);

			if ( spiroUnderCursor != current )
			{
				// click on a new (different) spiro

				if ( current >= 0 )
					// deactivate current
					CurrentSpiro.Selected=false;

				// activate this one
				SetCurrentSpiro(spiroUnderCursor);
				CurrentSpiro.Selected=true;

				// record the drag offset
				dragOffset=pt;
				dragOffset.Offset(-CurrentSpiro.Location.X,  -CurrentSpiro.Location.Y);

				// not too sure why we do this
				if ( captureHitInfo == HitInfo.Curve )
					captureHitInfo=HitInfo.Bounds;

				// create a clone to use to draw the highlight when dragging
				captureSpiro=CurrentSpiro.Clone();
				Invalidate();

				// all done
				return;
			}

			if ( current < 0 )
				// nothing selected so nothing to do - think this could be moved elsewhere
				return;

			// default case - click on current spiro

			// disable the animation
//			animateTimer.Enabled=false;

			// record the drag offset
			dragOffset=pt;
			dragOffset.Offset(-CurrentSpiro.Location.X,  -CurrentSpiro.Location.Y);
			// record the hit info for the point clicked
			captureHitInfo=CurrentSpiro.HitTest(pt, HitTestMode.Selected);
			// create a clone for highlighting
			captureSpiro=CurrentSpiro.Clone();
			capture=true;
		}
Beispiel #5
0
		private void DrawHighlight(SpiroInstance si, Graphics g, HitInfo hi, bool showInfo)
		{
			// simple helper
			si.DrawHighlight(g, hi);
			if ( showInfo )
			{
				Point pt=si.FocusRect.Location;
				pt.Offset(2,2);
				si.DrawInfo(g, pt, Color.Gray);
			}
		}
Beispiel #6
0
		public bool IntersectsAny(SpiroInstance test) 
		{
			foreach ( SpiroInstance si in spiros ) 
			{
				if ( si.Equals(test) )
					continue;

				if ( si.BoundingRect.IntersectsWith(test.BoundingRect) ) 
				{
					return true;
				}
			}
			return false;
		}
		private void AutoRandom(SpiroInstance si) 
		{
			while ( true ) 
			{
				si.ResetRandom();
				si.Colour=RandomColour();
				si.Location=RandomLocation();
				si.Speed=RandomSpeed();
				si.PenWidth=RandomLineThickness();
				if ( !spiroCanvas1.IntersectsAny(si) ) 
					break;
			}
		}
		public void Clone(SpiroInstance from)
		{
			// copy all properties from the other spiro

			this.location=from.location;

			this.R=from.R;
			this.r=from.r;
			this.f=from.f;
			this.counter=from.counter;

			// we can copy the points since they are essentially immutable
			// (if this spiro is changed in any way a new array is created)
			this.points=from.points;
			this.penWidth=from.penWidth;
			this.revolutions=from.revolutions;
			this.resolution=from.resolution;

			this.selected=from.selected;

			this.complete=from.complete;
			this.animate=from.animate;
			this.repeat=from.repeat;
			this.randomise=from.randomise;
			this.showInfo=from.showInfo;
			this.showTrace=from.ShowTrace;
			this.colour=from.colour;
			this.baseAngle=from.baseAngle;
			this.baseMovingAngle=from.baseMovingAngle;
			this.speed=from.speed;
			this.MaxRandomDiameter=from.MaxRandomDiameter;

			// only need to reset if we're a different type (ie. different points)
			if ( this.GetType() != from.GetType() )
				Reset();

			// ensure the circle sizes are valid
			if ( R < MinFixedRadius )
			{
				R=MinFixedRadius;
				Reset();
			}
			// it's not actually necessary to do this
			if ( r > MaxMovingRadius )
			{
				r=MaxMovingRadius;
				Reset();
			}
		}
		public void Resize(SpiroInstance current, int delta)
		{
			// this is a bit tricky - we need to resize both circles but give the same
			// (integer) ratio between them

			// in order to do this, each circle must increase/decrease by a multiple
			// of GCD(r,R)/size, ie. GCD(r,R)/R or GCD(r,R)/r

			// so we use the fixed circle as a base

			if ( delta == 0 )
				return;

			int d=current.R + delta;

			int multiple_R=R/GCD(r,R);
			int multiple_r=r/GCD(r,R);
			int new_R=(int) Math.Round((double) d/multiple_R)*multiple_R;
			int new_r=new_R * multiple_r / multiple_R;
			int new_f=(int) Math.Round(1.0 * f * (float) new_R / R);

			if ( new_R < 5 || new_r < 5 )
				// too small
				return;

			if ( new_R == R && new_r == r )
				return;

			SaveMovingAngle();
			R=new_R;
			r=new_r;
			f=new_f;
			Reset();
		}