using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
namespace Netron.Diagramming.Core {
///
/// This layout places nodes inside the visible area at a random location. The animation generated by this layout
/// allows you to see how nodes move from one location to another. Although it seems this layout does not
/// generate a clean organization is does help to perceive information in different perspectives and can be at times
/// really useful.
///
class RandomLayout : LayoutBase {
#region Fields
private const double speed = 0.1D;
private Random rnd;
double vectorx;
double vectory;
CollectionBase entities;
Dictionary speeds;
int width;
int height;
int x, y;
int time;
BackgroundWorker worker;
#endregion
#region Constructor
///
///Default constructor
///
public RandomLayout(IController controller)
: base("Random layout", controller) {
}
#endregion
#region Methods
///
/// Runs this instance.
///
public override void Run() {
width = this.Bounds.Width;
height = this.Bounds.Height;
Run(DefaultRunSpan);
}
///
/// Stops this instance.
///
public override void Stop() {
if (worker != null && worker.IsBusy)
worker.CancelAsync();
}
///
/// Runs the layout for a specified time.
///
/// The time.
public override void Run(int time) {
rnd = new Random();
entities = this.Model.CurrentPage.DefaultLayer.Entities;
speeds = new Dictionary();
foreach (IDiagramEntity entity in entities) {
if (entity is IShape) {
vectorx = -20 + 40 * rnd.NextDouble();
vectory = -20 + 40 * rnd.NextDouble();
speeds.Add(entity, new SpeedVector(vectorx, vectory));
}
}
this.time = time;
worker = new BackgroundWorker();
worker.DoWork += new DoWorkEventHandler(worker_DoWork);
worker.RunWorkerAsync(time);
}
void worker_DoWork(object sender, DoWorkEventArgs e) {
DateTime start = DateTime.Now;
while (DateTime.Now < start.AddMilliseconds((int)e.Argument)) {
RunStep();
}
}
///
/// Runs a single step.
///
private void RunStep() {
lock (entities)
lock (speeds) {
foreach (IDiagramEntity entity in entities) {
if (entity is IShape) {
x = Convert.ToInt32(speed * speeds[entity].X);
y = Convert.ToInt32(speed * speeds[entity].Y);
if (entity.Rectangle.X + x < width - entity.Rectangle.Width - 10 && entity.Rectangle.X + x > 10 && entity.Rectangle.Y + y < height - entity.Rectangle.Height - 10 && entity.Rectangle.Y + y > 10)
entity.MoveBy(new Point(x, y));
}
}
}
}
#endregion
}
}