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 } }