Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.ExtLibs/HeuristicLab.Netron/3.0.2672.12446/Netron.Diagramming.Core-3.0.2672.12446/Core/ViewBase.cs @ 2768

Last change on this file since 2768 was 2768, checked in by mkommend, 14 years ago

added solution folders and sources for the netron library (ticket #867)

File size: 57.4 KB
Line 
1using System;
2using System.ComponentModel;
3using System.Collections.Generic;
4using System.Text;
5using System.Drawing;
6using System.Drawing.Drawing2D;
7using System.Drawing.Design;
8using System.Diagnostics;
9using System.Windows.Forms;
10using System.Threading;
11using System.Drawing.Printing;
12
13namespace Netron.Diagramming.Core
14{
15    // ----------------------------------------------------------------------
16    /// <summary>
17    /// Abstract view base class which serves/renders both the Win and Web
18    /// diagrams.
19    /// <remarks>
20    /// <para>Click here for an explanation of the Model-View-Controller
21    /// pattern: http://st-www.cs.uiuc.edu/users/smarch/st-docs/mvc.html
22    /// </para>
23    /// <para>See Bob Powell's explaination of the different coordinate
24    /// systems here: http://www.bobpowell.net/mappingmodes.htm
25    /// The rendering pipeline with the different ratiometric conversions
26    /// is not really easy.
27    /// </para>
28    /// </remarks>
29    /// </summary>
30    // ----------------------------------------------------------------------
31    public abstract class ViewBase : IDisposable, IView
32    {
33
34        #region Events
35        /// <summary>
36        /// Occurs when the cursor changes and the surface has to effectively show a different cursor
37        /// </summary>
38        public event EventHandler<CursorEventArgs> OnCursorChange;
39        /// <summary>
40        /// Occurs when the background color has to change. The view could paint the backcolor itself via the PaintBackground method
41        /// but this would be less efficient than the built-in painting of the Control.
42        /// </summary>
43        public event EventHandler<ColorEventArgs> OnBackColorChange;
44        #endregion
45
46        #region Fields
47
48        // ------------------------------------------------------------------
49        /// <summary>
50        /// Specifies if all shape's connectors are shown.
51        /// </summary>
52        // ------------------------------------------------------------------
53        protected bool mShowConnectors = true;
54
55        // ------------------------------------------------------------------
56        /// <summary>
57        /// Specifies if the grid is drawn.
58        /// </summary>
59        // ------------------------------------------------------------------
60        protected bool mShowGrid = true;
61
62        // ------------------------------------------------------------------
63        /// <summary>
64        /// Specifies if a page's title is drawn when 'ShowPage' is set to
65        /// true.
66        /// </summary>
67        // ------------------------------------------------------------------
68        protected bool mShowPageTitle = false;
69
70        // ------------------------------------------------------------------
71        /// <summary>
72        /// Specifies if the page is rendered and printed in landscape
73        /// orientation.
74        /// </summary>
75        // ------------------------------------------------------------------
76        protected bool mLandscape = true;
77
78        protected  Matrix mViewMatrix;
79        protected  Matrix mInvertedViewMatrix;
80        private float dpiX = 96F;
81
82        private float dpiY = 96F;
83        /// <summary>
84        /// the ShowRulers field
85        /// </summary>
86        private bool mShowRulers;
87        private bool mIsSuspended;
88        /// <summary>
89        /// pointer to the current tracker
90        /// </summary>
91        private ITracker mTracker;
92        /// <summary>
93        /// pointer to the current ants or selector
94        /// </summary>
95        private IAnts mAnts;
96        /// <summary>
97        /// pointer to the current ghost bundle or region
98        /// </summary>
99        private IGhost mGhost;
100        /// <summary>
101        /// the data model
102        /// </summary>
103        private IModel mModel;
104        /// <summary>
105        /// the brush to be used for the background
106        /// </summary>
107        private Brush mBackgroundBrush;
108        /// <summary>
109        /// the parent control (aka surface)
110        /// </summary>
111        private IDiagramControl parentControl;
112        /// <summary>
113        /// the rectangle of the client surface
114        /// </summary>
115        private Rectangle clientRectangle;
116        /// <summary>
117        /// the current cursor
118        /// </summary>
119        private Cursor mCurrentCursor = Cursors.Default;
120
121        /// <summary>
122        /// the horizontal ruler
123        /// </summary>
124        private HorizontalRuler horizontalRuler;
125
126        /// <summary>
127        /// the vertical ruler
128        /// </summary>                                               
129        private VerticalRuler verticalRuler;
130        private int mRulerSize = 16;
131
132     
133
134        #endregion
135
136        #region Properties
137
138        // ------------------------------------------------------------------
139        /// <summary>
140        /// Gets or sets if the grid is to be drawn.
141        /// </summary>
142        // ------------------------------------------------------------------
143        public bool ShowGrid
144        {
145            get
146            {
147                return mShowGrid;
148            }
149            set
150            {
151                mShowGrid = value;
152                this.Invalidate();
153            }
154        }
155
156        // ------------------------------------------------------------------
157        /// <summary>
158        /// Specifies if all shape's connectors are shown.
159        /// </summary>
160        // ------------------------------------------------------------------
161        public bool ShowConnectors
162        {
163            get
164            {
165                return this.mModel.ShowConnectors;
166            }
167            set
168            {
169                this.mModel.ShowConnectors = value;
170                this.Invalidate();
171            }
172        }
173
174        // ------------------------------------------------------------------
175        /// <summary>
176        /// Gets or sets if the page's title is drawn when 'ShowPage' is set
177        /// to true.
178        /// </summary>
179        // ------------------------------------------------------------------
180        public bool ShowPageTitle
181        {
182            get
183            {
184                return mShowPageTitle;
185            }
186            set
187            {
188                mShowPageTitle = value;
189                this.Invalidate();
190            }
191        }
192
193        // ------------------------------------------------------------------
194        /// <summary>
195        /// Gets or sets the size of each page in thousandths of an inch.
196        /// </summary>
197        // ------------------------------------------------------------------
198        public Size PageSize
199        {
200            get
201            {
202                return mModel.CurrentPage.Ambience.PageSize;
203            }
204            set
205            {
206                foreach (IPage page in Model.Pages)
207                {
208                    page.Ambience.PageSize = value;
209                }
210                UpdateViewMatrix();
211                this.Invalidate();
212            }
213        }
214
215        // ------------------------------------------------------------------
216        /// <summary>
217        /// Gets or sets if each page is rendered and printed in landscape
218        /// orientation.
219        /// </summary>
220        // ------------------------------------------------------------------
221        public bool Landscape
222        {
223            get
224            {
225                return mLandscape;
226            }
227            set
228            {
229                mLandscape = value;
230                foreach (IPage page in mModel.Pages)
231                {
232                    page.Ambience.Landscape = value;
233                }
234                this.Invalidate();
235            }
236        }
237
238        // ------------------------------------------------------------------
239        /// <summary>
240        /// Gets or sets if the rulers are shown are not.  I don't recommend
241        /// showing them just yet :)
242        /// </summary>
243        // ------------------------------------------------------------------
244        public bool ShowRulers
245        {
246            get
247            {
248                return mShowRulers;
249            }
250            set
251            {
252                mShowRulers = value;
253                UpdateViewMatrix();
254                this.Invalidate();
255            }
256        }
257
258        // ------------------------------------------------------------------
259        /// <summary>
260        /// Gets the view matrix.
261        /// </summary>
262        /// <value>The view matrix.</value>
263        // ------------------------------------------------------------------
264        public Matrix ViewMatrix
265        {
266            get { return mViewMatrix; }
267        }
268
269        // ------------------------------------------------------------------
270        /// <summary>
271        /// Gets the inverted view matrix.
272        /// </summary>
273        // ------------------------------------------------------------------
274        public Matrix InvertedViewMatrix
275        {
276            get { return mInvertedViewMatrix; }
277        }
278
279        // ------------------------------------------------------------------
280        /// <summary>
281        /// Gets or sets the scaling factor of the current page.
282        /// </summary>
283        // ------------------------------------------------------------------
284        public SizeF Magnification
285        {
286            get
287            {
288                //return mMagnification;
289                return Model.CurrentPage.Magnification;
290            }
291            set
292            {   
293                Model.CurrentPage.Magnification = value;               
294                UpdateViewMatrix();
295                this.Invalidate();
296            }
297        }
298
299        // ------------------------------------------------------------------
300        /// <summary>
301        /// Pans the current page with the given shift.
302        /// </summary>
303        // ------------------------------------------------------------------
304        public Point Origin
305        {
306            get
307            {
308                return Model.CurrentPage.Origin;
309            }
310            set
311            {
312                Model.CurrentPage.Origin = value;
313                UpdateViewMatrix();
314                this.Invalidate();
315            }
316        }
317
318        // ------------------------------------------------------------------
319        /// <summary>
320        /// Gets the graphics object of the surface.
321        /// </summary>
322        // ------------------------------------------------------------------
323        public Graphics Graphics
324        {
325            get
326            { 
327                if (this.parentControl != null)
328                    return Graphics.FromHwnd((this.parentControl as Control).Handle);
329                else
330                    return null;
331            }
332        }
333
334        internal readonly static int TrackerOffset = 5;
335
336        // ------------------------------------------------------------------
337        /// <summary>
338        /// Gets the current cursor
339        /// </summary>
340        // ------------------------------------------------------------------
341        public Cursor CurrentCursor
342        {
343            get { return mCurrentCursor; }
344            set
345            {
346                mCurrentCursor = value;
347                RaiseOnCursorChange(value);
348            }
349        }
350
351        // ------------------------------------------------------------------
352        /// <summary>
353        /// Gets the background brush
354        /// </summary>
355        // ------------------------------------------------------------------
356        internal Brush BackgroundBrush
357        {
358            get
359            {
360                return mBackgroundBrush;
361            }
362        }
363
364        // ------------------------------------------------------------------
365        /// <summary>
366        /// Gets or sets the model
367        /// </summary>
368        // ------------------------------------------------------------------
369        public IModel Model
370        {
371            get
372            {
373                return mModel;
374            }
375            set
376            {
377                mModel = value;
378                AttachToModel(mModel);
379            }
380        }
381
382        // ------------------------------------------------------------------
383        /// <summary>
384        /// Gets the ghost.
385        /// </summary>
386        /// <value>The ghost.</value>
387        // ------------------------------------------------------------------
388        public  IGhost Ghost
389        {
390            get { return mGhost; }
391            protected set { mGhost = value;}
392        }
393
394        // ------------------------------------------------------------------
395        /// <summary>
396        /// Gets the ants.
397        /// </summary>
398        /// <value>The ants.</value>
399        // ------------------------------------------------------------------
400        public IAnts Ants
401        {
402            get { return mAnts; }
403            protected set { mAnts = value; }
404        }
405
406        // ------------------------------------------------------------------
407        /// <summary>
408        /// Gets or sets the tracker.
409        /// </summary>
410        /// <value>The tracker.</value>
411        // ------------------------------------------------------------------
412        public ITracker Tracker
413        {
414            get { return mTracker; }
415            set { mTracker = value; }
416        }
417
418        // ------------------------------------------------------------------
419        /// <summary>
420        /// Gets the client bounds.
421        /// </summary>
422        // ------------------------------------------------------------------
423        public Rectangle Bounds
424        {
425            get { return clientRectangle; }
426        }
427
428        [BrowsableAttribute(true)]
429        [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)]
430        public MeasurementsUnit RulerUnits
431        {
432            get
433            {
434                    return MeasurementsUnit.Inches;
435            }
436
437        }
438
439
440        #endregion
441
442        #region Constructor
443
444        // ------------------------------------------------------------------
445        ///<summary>
446        ///Default constructor
447        ///</summary>
448        // ------------------------------------------------------------------
449        protected ViewBase(IDiagramControl surface)
450        {
451            if (surface == null)
452                throw new NullReferenceException();
453
454            // Render and print each page in landscape.
455            mLandscape = true;
456
457            AttachToSurface(surface);
458        }
459
460        // ------------------------------------------------------------------
461        /// <summary>
462        /// Initializes a new instance of the <see cref="T:ViewBase"/> class.
463        /// </summary>
464        // ------------------------------------------------------------------
465        protected ViewBase()
466        { }
467       
468        #endregion
469
470        #region Methods
471
472        // ------------------------------------------------------------------
473        /// <summary>
474        /// Updates the view and inverted view matrices.
475        /// </summary>
476        // ------------------------------------------------------------------
477        private void UpdateViewMatrix()
478        {
479            mViewMatrix = GetViewMatrix();
480            //set the inverted view matrix
481            mInvertedViewMatrix = mViewMatrix.Clone();
482            mInvertedViewMatrix.Invert();
483        }
484
485        // ------------------------------------------------------------------
486        /// <summary>
487        /// Handles the SizeChanged event of the parentControl control.
488        /// </summary>
489        /// <param name="sender">The source of the event.</param>
490        /// <param name="e">The <see cref="T:System.EventArgs"/> instance
491        /// containing the event data.</param>
492        // ------------------------------------------------------------------
493        void parentControl_SizeChanged(object sender, EventArgs e)
494        {
495            clientRectangle = Rectangle.Round(parentControl.ClientRectangle);
496            //redefine the brush in function of the chosen background type
497            SetBackgroundType(Model.CurrentPage.Ambience.BackgroundType);
498            Invalidate();
499        }
500
501        // ------------------------------------------------------------------
502        /// <summary>
503        /// Paints the diagram on the canvas. Adornments and other stuff
504        /// (ghosts, ants and so on) have to be painted by descendants.
505        /// </summary>
506        /// <param name="g">the graphics onto which the diagram will be
507        /// painted</param>
508        // ------------------------------------------------------------------
509        public virtual void Paint(Graphics g)
510        {
511            if (mIsSuspended) return;
512            this.UpdateViewMatrix();
513            //Rectangle rectangle = WorkArea;
514            g.SetClip(WorkArea);
515            //g.PageUnit = Model.MeasurementUnits;
516            //g.PageScale = Model.MeasurementScale;
517           
518            //RectangleF rectangleF = ViewToWorld(DeviceToView(rectangle));
519            g.Transform = mViewMatrix;
520            mModel.CurrentPage.Paint(g, mShowGrid);
521        }
522       /*
523        public virtual void Draw(Graphics grfx)
524        {
525            Global.ViewMatrix = GetViewMatrix();
526            grfx.Clear(backgroundColor);
527            PaintRulers(grfx);
528            Rectangle rectangle = WorkArea;
529            grfx.SetClip(rectangle);
530            RectangleF rectangleF = ViewToWorld(DeviceToView(rectangle));
531            grfx.Transform = Global.ViewMatrix;
532            if (model != null)
533            {
534                grfx.PageUnit = model.MeasurementUnits;
535                grfx.PageScale = model.MeasurementScale;
536                model.DrawBackground(grfx);
537                LayoutGrid layoutGrid = Grid;
538                if (layoutGrid != null)
539                {
540                    layoutGrid.Draw(grfx);
541                }
542                if (ShowPageBounds)
543                {
544                    DrawPageBounds(grfx);
545                }
546                //draw the actual diagram
547                model.Draw(grfx, rectangleF);
548            }
549            grfx.Transform = new Matrix();
550            grfx.PageUnit = GraphicsUnit.Pixel;
551            grfx.PageScale = 1.0F;
552            DrawSelectionHandles(grfx);
553            isDirty = false;
554        }
555         */
556
557        // ------------------------------------------------------------------
558        /// <summary>
559        /// Gets the bounds of the current page, taking into account landscape
560        /// orientation and converting inches to dpi given the graphics
561        /// resolution.
562        /// </summary>
563        /// <param name="g">Graphics</param>
564        /// <returns>Rectangle</returns>
565        // ------------------------------------------------------------------
566        //protected RectangleF GetPageBounds(Graphics g)
567        //{
568        //    float width = (float)mModel.CurrentPage.Ambience.PageSize.Width / 1000;
569        //    float height = (float)mModel.CurrentPage.Ambience.PageSize.Height / 1000;
570        //    width = width * g.DpiX;
571        //    height = height * g.DpiY;
572
573        //    if (mModel.CurrentPage.Ambience.Landscape)
574        //    {
575        //        float w = width;
576        //        width = height;
577        //        height = w;
578        //    }
579
580        //    // Offset the upper-left corner by 1 inch.
581        //    float x = 1F * g.DpiX;
582        //    float y = 1F * g.DpiY;
583
584        //    RectangleF bounds = new RectangleF(x, y, width, height);
585        //    return bounds;
586        //}
587
588        // ------------------------------------------------------------------
589        /// <summary>
590        /// Paints the background.
591        /// </summary>
592        /// <param name="g">the graphics object onto which the background or
593        /// canvas will be painted</param>
594        // ------------------------------------------------------------------
595        public virtual void PaintBackground(Graphics g)
596        {
597            if (g == null) return;
598            if (mShowRulers)
599            {
600                PaintRulers(g);
601            }
602
603            g.SetClip(WorkArea);
604
605            if (mModel.CurrentPage.Ambience.BackgroundType ==
606                CanvasBackgroundTypes.FlatColor)
607            {
608                g.FillRectangle(
609                    new SolidBrush(mModel.CurrentPage.Ambience.BackgroundColor),
610                    clientRectangle);
611            }
612
613            RectangleF pageBounds = mModel.CurrentPage.Bounds;
614            g.Transform = mViewMatrix;
615            //g.TranslateTransform(pageLocation.X, pageLocation.Y);
616            RectangleF rec = pageBounds;
617
618            // The shadow
619            rec.Offset(6, 6);
620            g.FillRectangle(ArtPalette.ShadowBrush, rec);
621
622            // The page itself.
623            rec.Offset(-6, -6);
624            g.FillRectangle(
625                new SolidBrush(mModel.CurrentPage.Ambience.PageColor),
626                rec);
627            g.DrawRectangle(Pens.DimGray, rec.X, rec.Y, rec.Width, rec.Height);
628
629            if (mShowPageTitle)
630            {
631                g.DrawString(
632                    Model.CurrentPage.Ambience.Title,
633                    ArtPalette.TitleFont,
634                    Brushes.Silver,
635                    0,
636                    -50);
637            }
638            g.ResetTransform();
639        }
640
641        // ------------------------------------------------------------------
642        /// <summary>
643        /// Attaches event handlers to the events raised by the model.
644        /// </summary>
645        // ------------------------------------------------------------------
646        public void AttachToModel(IModel model)
647        {
648            if (model == null)
649                throw new ArgumentNullException(
650                    "The model assigned to the view cannot be 'null'");
651            // Should I do anything to dispose the current model before
652            // attaching the new one?
653            mModel = model;
654
655            mModel.OnAmbienceChanged +=
656                new EventHandler<AmbienceEventArgs>(mModel_OnAmbienceChanged);
657
658            mModel.OnInvalidate +=
659                new EventHandler(mModel_OnInvalidate);
660
661            mModel.OnInvalidateRectangle +=
662                new EventHandler<RectangleEventArgs>(
663                mModel_OnInvalidateRectangle);
664
665            mModel.OnCursorChange +=
666                new EventHandler<CursorEventArgs>(mModel_OnCursorChange);
667        }
668
669        // ------------------------------------------------------------------
670        /// <summary>
671        /// Attaches the view to the diagram control (aka surface).
672        /// </summary>
673        /// <param name="surface"></param>
674        // ------------------------------------------------------------------
675        private void AttachToSurface(IDiagramControl surface)
676        {
677
678            if (surface != null)
679            {
680                this.parentControl = surface;
681                Graphics graphics = this.Graphics;
682                dpiX = graphics.DpiX;
683                dpiY = graphics.DpiX;
684                graphics.Dispose();
685
686               
687                clientRectangle =
688                    Rectangle.Round(parentControl.ClientRectangle);
689
690                this.parentControl.SizeChanged +=
691                    new EventHandler(parentControl_SizeChanged);
692            }
693            else
694                throw new InconsistencyException("The surface control is 'null'");
695        }
696
697        void mModel_OnCursorChange(object sender, CursorEventArgs e)
698        {
699            this.RaiseOnCursorChange(e.Cursor);
700        }
701
702        void mModel_OnInvalidateRectangle(object sender, RectangleEventArgs e)
703        {
704
705            try
706            {
707                if (!mIsSuspended)
708                {
709                    Invalidate(e.Rectangle);
710                    ShowTracker();//this makes sure that the tracker is always
711                    // up to date, especially when the shape have
712                    // changed/trasnformed because of collapse/expand of material
713                }
714            }
715            catch(StackOverflowException)
716            {
717                //TODO: automatic exception report here?
718
719                throw;
720            }
721        }
722
723        // ------------------------------------------------------------------
724        /// <summary>
725        /// Handles the OnInvalidate event of the Model.
726        /// </summary>
727        /// <param name="sender">The source of the event.</param>
728        /// <param name="e">The <see cref="T:System.EventArgs"/> instance
729        /// containing the event data.</param>
730        // ------------------------------------------------------------------
731        void mModel_OnInvalidate(object sender, EventArgs e)
732        {
733            if (!mIsSuspended)
734            {
735                parentControl.Invalidate();
736            }
737        }
738
739        // ------------------------------------------------------------------
740        /// <summary>
741        /// Sets the type of the background.
742        /// </summary>
743        /// <param name="value">The value.</param>
744        // ------------------------------------------------------------------
745        public void SetBackgroundType(CanvasBackgroundTypes value)
746        {
747
748            if (value == CanvasBackgroundTypes.Gradient)
749            {
750                BuildGradientBrush();
751            }
752            else if (value == CanvasBackgroundTypes.FlatColor)
753            {
754                RaiseOnBackColorChange(
755                    Model.CurrentPage.Ambience.BackgroundColor);
756            }
757                //BuildSolidBrush();
758
759
760        }
761
762        // ------------------------------------------------------------------
763        /// <summary>
764        /// Handles the OnAmbienceChanged event of the mModel control.
765        /// </summary>
766        /// <param name="sender">The source of the event.</param>
767        /// <param name="e">The <see
768        /// cref="T:Netron.Diagramming.Core.AmbienceEventArgs"/> instance
769        /// containing the event data.</param>
770        // ------------------------------------------------------------------
771        void mModel_OnAmbienceChanged(object sender, AmbienceEventArgs e)
772        {
773            //redefine the brush in function of the chosen background type
774            SetBackgroundType(mModel.CurrentPage.Ambience.BackgroundType);
775            //refresh everything
776            Invalidate();
777        }
778
779        // ------------------------------------------------------------------
780        /// <summary>
781        /// Detaches from a model
782        /// </summary>
783        /// <param name="model">a diagram model</param>
784        // ------------------------------------------------------------------
785        public void DetachFromModel(Model model)
786        {
787            throw new System.NotImplementedException();
788        }
789
790        #region Invalidate overloads
791
792        // ------------------------------------------------------------------
793        /// <summary>
794        /// Invalidates this instance.
795        /// </summary>
796        // ------------------------------------------------------------------
797        public void Invalidate()
798        {
799            if (parentControl != null)
800            {
801                UpdateViewMatrix();
802                parentControl.Invalidate();
803            }
804        }
805
806        // ------------------------------------------------------------------
807        /// <summary>
808        /// Invalidates the specified rectangle.
809        /// </summary>
810        /// <param name="rectangle">The rectangle.</param>
811        // ------------------------------------------------------------------
812        public void Invalidate(Rectangle rectangle)
813        {
814            if (parentControl != null)
815            {
816                UpdateViewMatrix();                                                   
817                rectangle = Rectangle.Round(WorldToView(rectangle));
818                //rectangle.Offset(parentControl.AutoScrollPosition.X, parentControl.AutoScrollPosition.Y);
819                //rectangle = Rectangle.Round(ViewToWorld(DeviceToView(rectangle)));
820                this.parentControl.Invalidate(rectangle);
821            }
822        }
823        #endregion
824
825        // ------------------------------------------------------------------
826        /// <summary>
827        /// Builds the gradient brush.
828        /// </summary>
829        // ------------------------------------------------------------------
830        private void BuildGradientBrush()
831        {
832            if ( (mModel == null) || (clientRectangle == RectangleF.Empty) )
833            {
834                return;
835            }
836
837            mBackgroundBrush = new LinearGradientBrush(
838                clientRectangle,
839                mModel.CurrentPage.Ambience.BackgroundGradientColor1,
840                mModel.CurrentPage.Ambience.BackgroundGradientColor2,
841                LinearGradientMode.Vertical);
842        }
843
844        // ------------------------------------------------------------------
845        /// <summary>
846        /// Builds the solid brush.
847        /// </summary>
848        // ------------------------------------------------------------------
849        private void BuildSolidBrush()
850        {
851            if (mModel == null || clientRectangle == RectangleF.Empty) return;
852               
853            mBackgroundBrush = new SolidBrush(mModel.CurrentPage.Ambience.BackgroundColor);
854        }
855
856        // ------------------------------------------------------------------
857        /// <summary>
858        /// Raises the <see cref="OnCursorChange"/> event.
859        /// </summary>
860        /// <param name="cursor">The cursor.</param>
861        // ------------------------------------------------------------------
862        private void RaiseOnCursorChange(Cursor cursor)
863        {
864            EventHandler<CursorEventArgs> handler = OnCursorChange;
865            if (handler != null)
866                handler(this, new CursorEventArgs(cursor));
867        }
868
869        // ------------------------------------------------------------------
870        /// <summary>
871        /// Raises the OnBakcColorChange event.
872        /// </summary>
873        /// <param name="color">The color.</param>
874        // ------------------------------------------------------------------
875        private void RaiseOnBackColorChange(Color color)
876        {
877            EventHandler<ColorEventArgs> handler = OnBackColorChange;
878            if(handler != null)
879                handler(this, new ColorEventArgs(color));
880        }
881
882        // ------------------------------------------------------------------
883        /// <summary>
884        /// Paints the ants rectangle.
885        /// </summary>
886        /// <param name="ltPoint">The lt point.</param>
887        /// <param name="rbPoint">The rb point.</param>
888        // ------------------------------------------------------------------
889        public virtual void PaintAntsRectangle(Point ltPoint, Point rbPoint)
890        {
891        }
892
893        // ------------------------------------------------------------------
894        /// <summary>
895        /// Paints the ghost rectangle.
896        /// </summary>
897        /// <param name="ltPoint">The lt point.</param>
898        /// <param name="rbPoint">The rb point.</param>
899        // ------------------------------------------------------------------
900        public virtual void PaintGhostRectangle(Point ltPoint, Point rbPoint)
901        {
902        }
903
904        // ------------------------------------------------------------------
905        /// <summary>
906        /// Paints the ghost line.
907        /// </summary>
908        /// <param name="ltPoint">The lt point.</param>
909        /// <param name="rbPoint">The rb point.</param>
910        // ------------------------------------------------------------------
911        public virtual void PaintGhostLine(Point ltPoint, Point rbPoint)
912        {
913        }
914
915        // ------------------------------------------------------------------
916        /// <summary>
917        /// Paints the ghost line.
918        /// </summary>
919        /// <param name="curveType">Type of the curve.</param>
920        /// <param name="points">The points.</param>
921        // ------------------------------------------------------------------
922        public virtual void PaintGhostLine(MultiPointType curveType, Point[] points)
923        {
924        }
925
926        // ------------------------------------------------------------------
927        /// <summary>
928        /// Paints the ghost ellipse.
929        /// </summary>
930        /// <param name="ltPoint">The lt point.</param>
931        /// <param name="rbPoint">The rb point.</param>
932        // ------------------------------------------------------------------
933        public virtual void PaintGhostEllipse(Point ltPoint, Point rbPoint)
934        {
935        }
936
937        // ------------------------------------------------------------------
938        /// <summary>
939        /// Paints the tracker.
940        /// </summary>
941        /// <param name="rectangle">The rectangle.</param>
942        /// <param name="showHandles">if set to <c>true</c> shows the
943        /// handles.</param>
944        // ------------------------------------------------------------------
945        public virtual void PaintTracker(Rectangle rectangle, bool showHandles)
946        { }
947
948        // ------------------------------------------------------------------
949        /// <summary>
950        /// Resets the ghost.
951        /// </summary>
952        // ------------------------------------------------------------------
953        public void ResetGhost()
954        {
955            if (mGhost == null) return;
956            Rectangle rec = mGhost.Rectangle;
957            rec.Inflate(20, 20);
958            //convert it to viewspace
959            //rec = Rectangle.Round(WorldToView(rec));
960            this.Invalidate(rec);           
961            mGhost = null;
962        }
963
964        // ------------------------------------------------------------------
965        /// <summary>
966        /// Resets the ants.
967        /// </summary>
968        // ------------------------------------------------------------------
969        public void ResetAnts()
970        {
971            mAnts = null;
972        }
973
974        #region Tracker methods
975
976        // ------------------------------------------------------------------
977        /// <summary>
978        /// Resets the tracker.
979        /// </summary>
980        // ------------------------------------------------------------------
981        public void ResetTracker()
982        {
983            if (mTracker == null) return;
984            Rectangle rec = mTracker.Rectangle;
985            rec.Inflate(20, 20);
986            mTracker = null;
987            Invalidate(rec);
988        }
989
990        // ------------------------------------------------------------------
991        /// <summary>
992        /// Hides the tracker.
993        /// </summary>
994        // ------------------------------------------------------------------
995        public void HideTracker()
996        {
997            if(mTracker==null) return;
998            //let's be efficient and refresh only what's necessary
999            Rectangle rec = mTracker.Rectangle;
1000            rec.Inflate(20,20);
1001            mTracker = null;
1002            this.Invalidate(rec);
1003        }
1004
1005        // ------------------------------------------------------------------
1006        /// <summary>
1007        /// Shows the tracker.
1008        /// </summary>
1009        // ------------------------------------------------------------------
1010        public void ShowTracker()
1011        {
1012            if(Selection.SelectedItems != null &&
1013                Selection.SelectedItems.Count > 0)
1014            {
1015                CollectionBase<IDiagramEntity> ents = Selection.SelectedItems;
1016                bool showHandles = false;
1017
1018                Rectangle rec = ents[0].Rectangle;
1019                foreach (IDiagramEntity entity in ents)
1020                {
1021                    rec = Rectangle.Union(rec, entity.Rectangle);
1022                    showHandles |= entity.Resizable;
1023                }
1024                // Make the tracker slightly bigger than the actual bounding
1025                // rectangle.
1026                rec.Inflate(TrackerOffset, TrackerOffset);
1027
1028                this.PaintTracker(rec,showHandles);
1029
1030            }
1031            else //if the selection is 'null' or empty we annihilate the current tracker
1032                ResetTracker();
1033        }
1034        #endregion
1035
1036        // ------------------------------------------------------------------
1037        /// <summary>
1038        /// Suspends the invalidation of the view, which means that the
1039        /// Invalidate() method calls from any entity will be discarded until
1040        /// Resume() has been called.
1041        /// </summary>
1042        // ------------------------------------------------------------------
1043        public void Suspend()
1044        {
1045            mIsSuspended = true;
1046        }
1047
1048        // ------------------------------------------------------------------
1049        /// <summary>
1050        /// Resumes the invalidation of the view.
1051        /// </summary>
1052        // ------------------------------------------------------------------
1053        public void Resume()
1054        {
1055            mIsSuspended = false;
1056            parentControl.Invalidate();
1057        }
1058
1059        #region Rulers
1060       
1061        // ------------------------------------------------------------------
1062        /// <summary>
1063        /// Paints the horizontal and vertical rulers.
1064        /// </summary>
1065        /// <param name="g">Graphics</param>
1066        // ------------------------------------------------------------------
1067        protected virtual void PaintRulers(Graphics g)
1068        {
1069            PaintMarginIntersection(g);
1070            HorizontalRuler horizontalRuler = HorizontalRuler;
1071            if (horizontalRuler != null && horizontalRuler.Visible)
1072            {
1073                horizontalRuler.Paint(g);
1074            }
1075            VerticalRuler verticalRuler = VerticalRuler;
1076            if (verticalRuler != null && verticalRuler.Visible)
1077            {
1078                verticalRuler.Paint(g);
1079            }
1080        }
1081
1082        protected virtual void PaintMarginIntersection(Graphics g)
1083        {
1084            Rectangle rectangle = new Rectangle(Bounds.X, Bounds.Y, LeftMargin, TopMargin);
1085            g.FillRectangle(ArtPalette.RullerFillBrush, rectangle);
1086        }
1087
1088        protected virtual HorizontalRuler CreateHorizontalRuler()
1089        {
1090            return new HorizontalRuler(this);
1091        }
1092
1093        protected virtual VerticalRuler CreateVerticalRuler()
1094        {
1095            return new VerticalRuler(this);
1096        }
1097
1098        [BrowsableAttribute(true)]
1099        [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)]
1100        public int RulerSize
1101        {
1102            get
1103            {
1104                return mRulerSize;
1105            }
1106
1107            set
1108            {
1109                mRulerSize = value;
1110            }
1111        }
1112
1113        [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)]
1114        [BrowsableAttribute(false)]
1115        public virtual int LeftMargin
1116        {
1117            get
1118            {
1119                if ((verticalRuler != null) &&
1120                (verticalRuler.Visible) &&
1121                (mShowRulers))
1122                {
1123                    return RulerSize;
1124                }
1125                else
1126                {
1127                    return 0;
1128                }
1129            }
1130        }
1131        [BrowsableAttribute(false)]
1132        [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)]
1133        public virtual int TopMargin
1134        {
1135            get
1136            {
1137                if ((horizontalRuler != null) &&
1138                    (horizontalRuler.Visible) &&
1139                    (mShowRulers))
1140                {
1141                    return RulerSize;
1142                }
1143                else
1144                    return 0;
1145            }
1146        }
1147
1148        [BrowsableAttribute(false)]
1149        [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)]
1150        public Rectangle LeftMarginBounds
1151        {
1152            get
1153            {
1154                return new Rectangle(
1155                    Bounds.X,
1156                    Bounds.Y,
1157                    LeftMargin,
1158                    Bounds.Height);
1159            }
1160        }
1161
1162
1163
1164        [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)]
1165        [BrowsableAttribute(false)]
1166        public Rectangle TopMarginBounds
1167        {
1168            get
1169            {
1170                return new Rectangle(
1171                    Bounds.X,
1172                    Bounds.Y,
1173                    Bounds.Width,
1174                    TopMargin);
1175            }
1176        }
1177
1178        /// <summary>
1179        /// Gets the work area, i.e. the rectangle of the surface control without the rulers.
1180        /// </summary>
1181        /// <value>The work area.</value>
1182        [BrowsableAttribute(false)]
1183        [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)]
1184        public virtual Rectangle WorkArea
1185        {
1186            get
1187            {
1188                Rectangle rectangle = Bounds;
1189                rectangle.X = rectangle.Left + LeftMargin + 1;
1190                rectangle.Y = rectangle.Top + TopMargin + 1;
1191                return rectangle;
1192            }
1193        }
1194
1195        [BrowsableAttribute(false)]
1196        [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)]
1197        public Rectangle HorizontalRulerBounds
1198        {
1199            get
1200            {
1201                int lm = LeftMargin;
1202                int tm = TopMargin;
1203                return new Rectangle(Bounds.X + lm, Bounds.Y, Bounds.Width - lm, tm);
1204            }
1205        }
1206
1207        [BrowsableAttribute(false)]
1208        [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)]
1209        public Rectangle VerticalRulerBounds
1210        {
1211            get
1212            {
1213                int i = LeftMargin;
1214                int j = TopMargin;
1215                return new Rectangle(Bounds.X, Bounds.Y + j, i, Bounds.Height - j);
1216            }
1217        }
1218        [CategoryAttribute("Rulers")]
1219        [BrowsableAttribute(true)]
1220        [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Content)]
1221        public HorizontalRuler HorizontalRuler
1222        {
1223            get
1224            {
1225                if (horizontalRuler == null)
1226                {
1227                    horizontalRuler = CreateHorizontalRuler();
1228                }
1229                return horizontalRuler;
1230            }
1231        }
1232
1233        [DesignerSerializationVisibilityAttribute(
1234            DesignerSerializationVisibility.Content)]
1235        [BrowsableAttribute(true)]
1236        [CategoryAttribute("Rulers")]
1237        public VerticalRuler VerticalRuler
1238        {
1239            get
1240            {
1241                if (verticalRuler == null)
1242                {
1243                    verticalRuler = CreateVerticalRuler();
1244                }
1245                return verticalRuler;
1246            }
1247        }
1248        #endregion
1249
1250        #region World-View-Device Conversions
1251
1252        #region View to device
1253        public Point ViewToDevice(PointF ptView)
1254        {
1255            float f1 = 1.0F;
1256            float f2 = 1.0F;
1257            float f3 = 1.0F;
1258            float f4 = 1.0F;
1259            if (mModel != null)
1260            {
1261                if (mModel.MeasurementUnits != GraphicsUnit.Pixel)
1262                {
1263                    f1 = Measurements.UnitsPerInch(mModel.MeasurementUnits);
1264                    f3 = dpiX / f1;
1265                    f4 = dpiX / f1;
1266                }
1267                f2 = mModel.MeasurementScale;
1268            }
1269            int i = (int)Math.Round((double)(ptView.X * f2 * f3));
1270            int j = (int)Math.Round((double)(ptView.Y * f2 * f4));
1271            return new Point(i, j);
1272        }
1273
1274        public Size ViewToDevice(SizeF szView)
1275        {
1276            float f1 = 1.0F;
1277            float f2 = 1.0F;
1278            float f3 = 1.0F;
1279            float f4 = 1.0F;
1280            if (mModel != null)
1281            {
1282                if (mModel.MeasurementUnits != GraphicsUnit.Pixel)
1283                {
1284                    f1 = Measurements.UnitsPerInch(mModel.MeasurementUnits);
1285                    f3 = dpiX / f1;
1286                    f4 = dpiX / f1;
1287                }
1288                f2 = mModel.MeasurementScale;
1289            }
1290            int i = (int)(szView.Width * f2 * f3);
1291            int j = (int)(szView.Height * f2 * f4);
1292            return new Size(i, j);
1293        }
1294
1295        public PointF ViewToDeviceF(PointF ptView)
1296        {
1297            float f3 = 1.0F;
1298            float f4 = 1.0F;
1299            float f5 = 1.0F;
1300            float f6 = 1.0F;
1301            if (mModel != null)
1302            {
1303                if (mModel.MeasurementUnits != GraphicsUnit.Pixel)
1304                {
1305                    f3 = Measurements.UnitsPerInch(mModel.MeasurementUnits);
1306                    f5 = dpiX / f3;
1307                    f6 = dpiX / f3;
1308                }
1309                f4 = mModel.MeasurementScale;
1310            }
1311            float f1 = ptView.X * f4 * f5;
1312            float f2 = ptView.Y * f4 * f6;
1313            return new PointF(f1, f2);
1314        }
1315
1316        public Rectangle ViewToDevice(RectangleF rcView)
1317        {
1318            PointF pointF1 = new PointF(rcView.Left, rcView.Top);
1319            PointF pointF2 = new PointF(rcView.Right, rcView.Bottom);
1320            Point point1 = ViewToDevice(pointF1);
1321            Point point2 = ViewToDevice(pointF2);
1322            return new Rectangle(point1.X, point1.Y, point2.X - point1.X, point2.Y - point1.Y);
1323        }
1324
1325        public void ViewToDevice(PointF[] viewPts, out Point[] devicePts)
1326        {
1327            devicePts = new Point[(int)viewPts.Length];
1328            for (int i = 0; i < (int)viewPts.Length; i++)
1329            {
1330                devicePts[i] = ViewToDevice(viewPts[i]);
1331            }
1332        }
1333
1334        public SizeF ViewToDeviceF(SizeF szView)
1335        {
1336            float f3 = 1.0F;
1337            float f4 = 1.0F;
1338            float f5 = 1.0F;
1339            float f6 = 1.0F;
1340            if (mModel != null)
1341            {
1342                if (mModel.MeasurementUnits != GraphicsUnit.Pixel)
1343                {
1344                    f3 = Measurements.UnitsPerInch(mModel.MeasurementUnits);
1345                    f5 = dpiX / f3;
1346                    f6 = dpiX / f3;
1347                }
1348                f4 = mModel.MeasurementScale;
1349            }
1350            float f1 = szView.Width * f4 * f5;
1351            float f2 = szView.Height * f4 * f6;
1352            return new SizeF(f1, f2);
1353        }
1354
1355        public RectangleF ViewToDeviceF(RectangleF rcView)
1356        {
1357            PointF pointF1 = new PointF(rcView.Left, rcView.Top);
1358            PointF pointF2 = new PointF(rcView.Right, rcView.Bottom);
1359            PointF pointF3 = ViewToDeviceF(pointF1);
1360            PointF pointF4 = ViewToDeviceF(pointF2);
1361            return new RectangleF(pointF3.X, pointF3.Y, pointF4.X - pointF3.X, pointF4.Y - pointF3.Y);
1362        }
1363        #endregion
1364
1365        #region World to view
1366
1367        public RectangleF WorldToView(RectangleF rcWorld)
1368        {
1369            PointF[] pointFs = new PointF[2];
1370            pointFs[0].X = rcWorld.Left;
1371            pointFs[0].Y = rcWorld.Top;
1372            pointFs[1].X = rcWorld.Right;
1373            pointFs[1].Y = rcWorld.Bottom;
1374            mViewMatrix.TransformPoints(pointFs);
1375            return new RectangleF(pointFs[0].X, pointFs[0].Y, pointFs[1].X - pointFs[0].X, pointFs[1].Y - pointFs[0].Y);
1376        }
1377
1378        public PointF WorldToView(PointF ptWorld)
1379        {
1380            PointF[] pointFs1 = new PointF[] { ptWorld };
1381            mViewMatrix.TransformPoints(pointFs1);
1382            return pointFs1[0];
1383        }
1384
1385        public void WorldToView(PointF[] worldPts, out PointF[] viewPts)
1386        {
1387            viewPts = (PointF[])worldPts.Clone();
1388            mViewMatrix.TransformPoints(viewPts);
1389        }
1390
1391        public SizeF WorldToView(SizeF szWorld)
1392        {
1393            PointF[] pointFs1 = new PointF[] { new PointF(szWorld.Width, szWorld.Height) };
1394            Matrix matrix = new Matrix();
1395            matrix.Scale(Magnification.Width / 100.0F, Magnification.Height / 100.0F);
1396            matrix.TransformPoints(pointFs1);
1397            return new SizeF(pointFs1[0].X, pointFs1[0].Y);
1398        }
1399
1400        #endregion
1401
1402        #region View to world
1403
1404        /// <summary>
1405        /// Converts the given point from View coordinates to the absolute World coordinates.
1406        /// </summary>
1407        /// <param name="ptView">The pt view.</param>
1408        /// <returns></returns>
1409        public PointF ViewToWorld(PointF ptView)
1410        {
1411            PointF[] pointFs1 = new PointF[] { ptView };
1412            //Matrix matrix = mInvertedViewMatrix;
1413            //the view transformation has to be inverted since the transform is from world to view coordinates
1414            //matrix.Invert();
1415            mInvertedViewMatrix.TransformPoints(pointFs1);
1416            return pointFs1[0];
1417        }
1418
1419        /// <summary>
1420        /// Converts the given rectangle from View coordinates to the absolute World coordinates.
1421        /// </summary>
1422        /// <param name="rcView">The rc view.</param>
1423        /// <returns></returns>
1424        public RectangleF ViewToWorld(RectangleF rcView)
1425        {
1426            PointF[] pointFs = new PointF[2];
1427            pointFs[0].X = rcView.Left;
1428            pointFs[0].Y = rcView.Top;
1429            pointFs[1].X = rcView.Right;
1430            pointFs[1].Y = rcView.Bottom;
1431            //Matrix matrix = GetViewMatrix();
1432            //matrix.Invert();
1433            mInvertedViewMatrix.TransformPoints(pointFs);
1434            return new RectangleF(pointFs[0].X, pointFs[0].Y, pointFs[1].X - pointFs[0].X, pointFs[1].Y - pointFs[0].Y);
1435        }
1436
1437        /// <summary>
1438        /// Converts the given rectangle from View coordinates to the absolute World coordinates.
1439        /// </summary>
1440        /// <param name="rectangle">The rectangle.</param>
1441        /// <returns></returns>
1442        public Rectangle ViewToWorld(Rectangle rectangle)
1443        {
1444            Point[] pts = new Point[2];
1445            pts[0].X = rectangle.Left;
1446            pts[0].Y = rectangle.Top;
1447            pts[1].X = rectangle.Right;
1448            pts[1].Y = rectangle.Bottom;
1449            //Matrix matrix = GetViewMatrix();
1450            //matrix.Invert();
1451            mInvertedViewMatrix.TransformPoints(pts);
1452            return new Rectangle(pts[0].X, pts[0].Y, pts[1].X - pts[0].X, pts[1].Y - pts[0].Y);
1453        }
1454
1455        /// <summary>
1456        /// Converts the given size from View coordinates to the absolute World coordinates.
1457        /// </summary>
1458        /// <param name="szView">The sz view.</param>
1459        /// <returns></returns>
1460        public SizeF ViewToWorld(SizeF szView)
1461        {
1462            PointF[] pointFs1 = new PointF[] { new PointF(szView.Width, szView.Height) };
1463            Matrix matrix = new Matrix();
1464            matrix.Scale(Magnification.Width / 100.0F, Magnification.Height / 100.0F);
1465            matrix.Invert();
1466            matrix.TransformPoints(pointFs1);
1467            return new SizeF(pointFs1[0].X, pointFs1[0].Y);
1468        }
1469
1470        /// <summary>
1471        /// Converts the given point array from View coordinates to the absolute World coordinates.
1472        /// </summary>
1473        /// <param name="viewPts">The view PTS.</param>
1474        /// <param name="worldPts">The world PTS.</param>
1475        public void ViewToWorld(PointF[] viewPts, out PointF[] worldPts)
1476        {
1477            worldPts = (PointF[])viewPts.Clone();
1478            //Matrix matrix = GetViewMatrix();
1479            //matrix.Invert();
1480            mInvertedViewMatrix.TransformPoints(worldPts);
1481        }
1482
1483        #endregion
1484
1485        #region Device to view
1486
1487        public PointF DeviceToView(Point ptDevice)
1488        {
1489            float f3 = 1.0F;
1490            float f4 = 1.0F;
1491            float f5 = 1.0F;
1492            float f6 = 1.0F;
1493            if (mModel != null)
1494            {
1495                if (mModel.MeasurementUnits != GraphicsUnit.Pixel)
1496                {
1497                    f3 = Measurements.UnitsPerInch(mModel.MeasurementUnits);
1498                    f5 = dpiX / f3;
1499                    f6 = dpiY / f3;
1500                }
1501                f4 = mModel.MeasurementScale;
1502            }
1503            float f1 = (float)ptDevice.X / (f4 * f5);
1504            float f2 = (float)ptDevice.Y / (f4 * f6);
1505            return new PointF(f1, f2);
1506        }
1507
1508        public void DeviceToView(Point[] devicePts, out PointF[] viewPts)
1509        {
1510            viewPts = new PointF[(int)devicePts.Length];
1511            for (int i = 0; i < (int)devicePts.Length; i++)
1512            {
1513                viewPts[i] = DeviceToView(devicePts[i]);
1514            }
1515        }
1516
1517        public RectangleF DeviceToView(Rectangle rcDevice)
1518        {
1519            Point point1 = new Point(rcDevice.Left, rcDevice.Top);
1520            Point point2 = new Point(rcDevice.Right, rcDevice.Bottom);
1521            PointF pointF1 = DeviceToView(point1);
1522            PointF pointF2 = DeviceToView(point2);
1523            return new RectangleF(pointF1.X, pointF1.Y, pointF2.X - pointF1.X, pointF2.Y - pointF1.Y);
1524        }
1525
1526        public SizeF DeviceToView(Size szDevice)
1527        {
1528            float f3 = 1.0F;
1529            float f4 = 1.0F;
1530            float f5 = 1.0F;
1531            float f6 = 1.0F;
1532            if (mModel != null)
1533            {
1534                if (mModel.MeasurementUnits != GraphicsUnit.Pixel)
1535                {
1536                    f3 = Measurements.UnitsPerInch(mModel.MeasurementUnits);
1537                    f5 = dpiX / f3;
1538                    f6 = dpiY / f3;
1539                }
1540                f4 = mModel.MeasurementScale;
1541            }
1542            float f1 = (float)szDevice.Width / (f4 * f5);
1543            float f2 = (float)szDevice.Height / (f4 * f6);
1544            return new SizeF(f1, f2);
1545        }
1546
1547        #endregion
1548
1549        #endregion
1550
1551        // ------------------------------------------------------------------
1552        /// <summary>
1553        /// Returns the matrix corresponding to the translation and scaling
1554        /// of the canvas.
1555        /// </summary>
1556        /// <returns>Matrix</returns>
1557        // ------------------------------------------------------------------
1558        public Matrix GetViewMatrix()
1559        {
1560            Matrix matrix = new Matrix();
1561
1562            matrix.Scale(
1563                Magnification.Width / 100.0F,
1564                Magnification.Height / 100.0F);
1565
1566            matrix.Translate(-Origin.X, -Origin.Y);
1567
1568            Size size = new Size(LeftMargin, TopMargin);
1569            SizeF sizeF = ViewToWorld(DeviceToView(size));
1570            matrix.Translate(sizeF.Width, sizeF.Height);
1571            return matrix;
1572        }
1573
1574        // ------------------------------------------------------------------
1575        /// <summary>
1576        /// Sets the magnification and origin of the diagram such that
1577        /// all entities in the current page are in view.
1578        /// </summary>
1579        // ------------------------------------------------------------------
1580        public virtual void ZoomFit()
1581        {
1582            Bundle bundle = new Bundle(this.Model.CurrentPage.Entities);
1583            Rectangle bundleBounds = bundle.Rectangle;
1584            bundleBounds.Inflate(20, 20);
1585            bundleBounds.Offset(-10, -10);
1586            this.ZoomArea(bundleBounds);
1587        }
1588
1589        // ------------------------------------------------------------------
1590        /// <summary>
1591        /// Zooms the diagram to the area specified.
1592        /// </summary>
1593        /// <param name="areaInWorldCoords">Rectangle: The area to zoom in world
1594        /// coordinates.</param>
1595        // ------------------------------------------------------------------
1596        public virtual void ZoomArea(Rectangle areaInWorldCoords)
1597        {
1598            Rectangle areaToZoom = Rectangle.Round(WorldToView(areaInWorldCoords));
1599            areaToZoom = areaInWorldCoords;
1600
1601            float zoom = Math.Min(
1602                ((float)WorkArea.Width / (float)areaToZoom.Width) * 100.0F,
1603                 ((float)WorkArea.Height / (float)areaToZoom.Height) * 100.0F);
1604
1605            if (zoom == 0)
1606            {
1607                zoom = 1F;
1608            }
1609
1610            Magnification = new SizeF(
1611                zoom,
1612                zoom);
1613            Origin = areaInWorldCoords.Location;
1614        }
1615
1616        #endregion
1617
1618        #region Standard IDispose implementation
1619        /// <summary>
1620        /// Disposes the view
1621        /// </summary>
1622        public void Dispose()
1623        {
1624            Dispose(true);
1625            GC.SuppressFinalize(this);
1626
1627           
1628        }
1629        /// <summary>
1630        /// Disposes this instance.
1631        /// </summary>
1632        /// <param name="disposing">if set to <c>true</c> [disposing].</param>
1633        protected virtual void Dispose(bool disposing)
1634        {
1635            if(disposing)
1636            {
1637                #region free managed resources
1638                if(mBackgroundBrush != null)
1639                {
1640                    mBackgroundBrush.Dispose();
1641                    mBackgroundBrush = null;
1642                }
1643                #endregion
1644            }
1645           
1646        }
1647
1648        #endregion
1649   
1650    }
1651}
Note: See TracBrowser for help on using the repository browser.