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 @ 5809

Last change on this file since 5809 was 4068, checked in by swagner, 14 years ago

Sorted usings and removed unused usings in entire solution (#1094)

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