Windows.PlotSurface2D.cs

Go to the documentation of this file.
00001 /*
00002 NPlot - A charting library for .NET
00003 
00004 Windows.PlotSurface2d.cs
00005 Copyright (C) 2003 
00006 Matt Howlett
00007 
00008 Redistribution and use of NPlot or parts there-of in source and
00009 binary forms, with or without modification, are permitted provided
00010 that the following conditions are met:
00011 
00012 1. Re-distributions in source form must retain at the head of each
00013    source file the above copyright notice, this list of conditions
00014    and the following disclaimer.
00015 
00016 2. Any product ("the product") that makes use NPlot or parts 
00017    there-of must either:
00018   
00019     (a) allow any user of the product to obtain a complete machine-
00020         readable copy of the corresponding source code for the 
00021         product and the version of NPlot used for a charge no more
00022         than your cost of physically performing source distribution,
00023         on a medium customarily used for software interchange, or:
00024 
00025     (b) reproduce the following text in the documentation, about 
00026         box or other materials intended to be read by human users
00027         of the product that is provided to every human user of the
00028         product: 
00029    
00030               "This product includes software developed as 
00031               part of the NPlot library project available 
00032               from: http://www.nplot.com/" 
00033 
00034         The words "This product" may optionally be replace with 
00035         the actual name of the product.
00036 
00037 ------------------------------------------------------------------------
00038 
00039 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
00040 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00041 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
00042 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
00043 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
00044 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00045 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00046 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00047 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00048 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00049 
00050 */
00051 
00052 using System;
00053 using System.Collections;
00054 using System.ComponentModel;
00055 using System.Drawing;
00056 using System.Data;
00057 using System.Windows.Forms;
00058 using System.Drawing.Printing;
00059 
00060 using NPlot;
00061 
00062 namespace NPlot.Windows
00063 {
00064 
00071         [ ToolboxBitmapAttribute(typeof(NPlot.Windows.PlotSurface2D),"PlotSurface2D.ico") ]
00072         public class PlotSurface2D : System.Windows.Forms.Control, IPlotSurface2D, ISurface
00073         {
00074 
00075         private System.Windows.Forms.ToolTip coordinates_;
00076 
00077                 private System.Collections.ArrayList selectedObjects_;
00078         private NPlot.PlotSurface2D ps_;
00079 
00080                 private Axis xAxis1ZoomCache_;
00081                 private Axis yAxis1ZoomCache_;
00082                 private Axis xAxis2ZoomCache_;
00083                 private Axis yAxis2ZoomCache_;
00084 
00085 
00089                 [ 
00090                 Category("PlotSurface2D"),
00091                 Description("Whether or not to show coordinates in a tool tip when the mouse hovers above the plot area."),
00092                 Browsable(true),
00093                 Bindable(true)
00094                 ]
00095                 public bool ShowCoordinates
00096                 {
00097                         get
00098                         {
00099                                 return this.coordinates_.Active;
00100                         }
00101                         set
00102                         {
00103                                 this.coordinates_.Active = value;
00104                         }
00105                 }
00106 
00107 
00111                 public PlotSurface2D()
00112                 {
00113                         // This call is required by the Windows.Forms Form Designer.
00114                         InitializeComponent();
00115 
00116             // double buffer, and update when resize.
00117                         base.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
00118                         base.SetStyle(ControlStyles.DoubleBuffer, true);
00119                         base.SetStyle(ControlStyles.UserPaint, true);
00120                         base.ResizeRedraw = true;
00121 
00122                         ps_ = new NPlot.PlotSurface2D();
00123 
00124             this.InteractionOccured += new InteractionHandler( OnInteractionOccured );
00125             this.PreRefresh += new PreRefreshHandler( OnPreRefresh );
00126                 }
00127 
00128 
00134                 private void InitializeComponent()
00135                 {
00136                         this.components = new System.ComponentModel.Container();
00137                         this.coordinates_ = new System.Windows.Forms.ToolTip(this.components);
00138                         // 
00139                         // PlotSurface2D
00140                         // 
00141                         this.BackColor = System.Drawing.SystemColors.ControlLightLight;
00142                         this.Size = new System.Drawing.Size(328, 272);
00143 
00144                 }
00145 
00146 
00147         KeyEventArgs lastKeyEventArgs_ = null;
00152         protected override void OnKeyDown(KeyEventArgs e)
00153         {
00154             lastKeyEventArgs_ = e;
00155         }
00156 
00161         protected override void OnKeyUp(KeyEventArgs e)
00162         {
00163             lastKeyEventArgs_ = e;
00164         }
00165 
00170                 protected override void OnPaint( PaintEventArgs pe )
00171                 {
00172                         DoPaint( pe, this.Width, this.Height );
00173                         base.OnPaint(pe);
00174                 }
00175 
00176 
00184                 public void DoPaint( PaintEventArgs pe, int width, int height )
00185                 {
00186             this.PreRefresh(this);
00187 
00188             foreach (Interactions.Interaction i in interactions_)
00189             {
00190                 i.DoPaint(pe,width,height);
00191             }
00192 
00193             /*
00194             // make sure don't redraw after a refresh.
00195             this.horizontalBarPos_ = -1;
00196             this.verticalBarPos_ = -1;
00197             */
00198 
00199             Graphics g = pe.Graphics;
00200                         
00201                         Rectangle border = new Rectangle( 0, 0, width, height );
00202 
00203                         if ( g == null ) 
00204                         {
00205                                 throw (new NPlotException("null graphics context!"));
00206                         }
00207                         
00208                         if ( ps_ == null )
00209                         {
00210                                 throw (new NPlotException("null NPlot.PlotSurface2D"));
00211                         }
00212                         
00213                         if ( border == Rectangle.Empty )
00214                         {
00215                                 throw (new NPlotException("null border context"));
00216                         }
00217 
00218                         this.Draw( g, border );
00219                 }
00220 
00221 
00228                 public void Draw( Graphics g, Rectangle bounds )
00229                 {
00230 
00231                         // If we are not in design mode then draw as normal.
00232                         if (LicenseManager.UsageMode == LicenseUsageMode.Designtime) 
00233                         { 
00234                                 this.drawDesignMode( g, bounds );
00235                         }
00236 
00237                         ps_.Draw( g, bounds );
00238                 
00239                 }
00240 
00241 
00245                 private void drawDesignMode( Graphics g, Rectangle bounds )
00246                 {
00247                         g.DrawRectangle( new Pen(Color.Black), bounds.X + 2, bounds.Y + 2, bounds.Width-4, bounds.Height-4 );
00248                         g.DrawString( "PlotSurface2D: " + this.Title, this.TitleFont, this.TitleBrush, bounds.X + bounds.Width/2.0f, bounds.Y + bounds.Height/2.0f );
00249                 }
00250 
00251 
00255                 public void Clear()
00256                 {
00257                         xAxis1ZoomCache_ = null;
00258                         yAxis1ZoomCache_ = null;
00259                         xAxis2ZoomCache_ = null;
00260                         yAxis2ZoomCache_ = null;
00261                         ps_.Clear();
00262             interactions_.Clear();
00263         }
00264 
00265 
00271                 public void Add( IDrawable p )
00272                 {
00273                         ps_.Add( p );
00274                 }
00275 
00276 
00284                 public void Add( IDrawable p, NPlot.PlotSurface2D.XAxisPosition xp, NPlot.PlotSurface2D.YAxisPosition yp )
00285                 {
00286                         ps_.Add( p, xp, yp );
00287                 }
00288 
00289 
00296                 public void Add( IDrawable p, int zOrder )
00297                 {
00298                         ps_.Add( p, zOrder );
00299                 }
00300 
00301 
00310                 public void Add( IDrawable p, NPlot.PlotSurface2D.XAxisPosition xp,
00311                         NPlot.PlotSurface2D.YAxisPosition yp, int zOrder )
00312                 {
00313                         ps_.Add( p, xp, yp , zOrder);
00314                 }
00315 
00316 
00320                 [
00321                 Browsable(false),
00322                 Bindable(false)
00323                 ]
00324                 public NPlot.Legend Legend
00325                 {
00326                         get
00327                         {
00328                                 return ps_.Legend;
00329                         }
00330                         set
00331                         {
00332                                 ps_.Legend = value;
00333                         }
00334                 }
00335 
00336 
00340                 [
00341                 Browsable(true),
00342                 Bindable(true),
00343                 Category("PlotSurface2D"),
00344                 Description("Determines the order with respect to other IDrawables on the plot surface in which the legend is drawn. " +
00345                         "The higher this value, the higher the position in the draw order." )
00346                 ]
00347                 public int LegendZOrder
00348                 {
00349                         get
00350                         {
00351                                 return ps_.LegendZOrder;
00352                         }
00353                         set
00354                         {
00355                                 ps_.LegendZOrder = value;
00356                         }
00357                 }
00358 
00359 
00364                 [
00365                 Browsable(true),
00366                 Bindable(true),
00367                 Description("Whether or not the title will be scaled according to size of the plot surface."),
00368                 Category("PlotSurface2D")
00369                 ]
00370                 public bool AutoScaleTitle
00371                 {
00372                         get
00373                         {
00374                                 return ps_.AutoScaleTitle;
00375                         }
00376                         set
00377                         {
00378                                 ps_.AutoScaleTitle = value;
00379                         }
00380                 }
00381 
00382 
00391                 [
00392                 Browsable(true),
00393                 Bindable(true),
00394                 Description( "When plots are added to the plot surface, the axes they are attached to are immediately modified " +
00395                         "to reflect data of the plot. If AutoScaleAutoGeneratedAxes is true when a plot is added, the axes will be " +
00396                         "turned in to auto scaling ones if they are not already [tick marks, tick text and label size scaled to size " +
00397                         "of plot surface]. If false, axes will not be autoscaling." ),
00398                 Category("PlotSurface2D")
00399                 ]
00400                 public bool AutoScaleAutoGeneratedAxes
00401                 {
00402                         get
00403                         {
00404                                 return ps_.AutoScaleAutoGeneratedAxes;
00405                         }
00406                         set
00407                         {
00408                                 ps_.AutoScaleAutoGeneratedAxes = value;
00409                         }
00410                 }
00411 
00412 
00416                 [
00417                 Category("PlotSurface2D"),
00418                 Description("The plot surface title"),
00419                 Browsable(true),
00420                 Bindable(true)
00421                 ]
00422                 public string Title
00423                 {
00424                         get 
00425                         {
00426                                 return ps_.Title;
00427                         }
00428                         set 
00429                         {
00430                                 ps_.Title = value;
00431                                 //helpful in design view. But crap in applications!
00432                                 //this.Refresh();
00433                         }
00434                 }
00435 
00436 
00440                 [
00441                 Category("PlotSurface2D"),
00442                 Description("The font used to draw the title."),
00443                 Browsable(true),
00444                 Bindable(false)
00445                 ]
00446                 public Font TitleFont 
00447                 {
00448                         get 
00449                         {
00450                                 return ps_.TitleFont;
00451                         }
00452                         set 
00453                         {
00454                                 ps_.TitleFont = value;
00455                         }
00456                 }
00457 
00458 
00462                 [
00463                 Category("PlotSurface2D"),
00464                 Description("Padding of this width will be left between what is drawn and the control border."),
00465                 Browsable(true),
00466                 Bindable(true)
00467                 ]
00468                 public int Padding
00469                 {
00470                         get
00471                         {
00472                                 return ps_.Padding;
00473                         }
00474                         set
00475                         {
00476                                 ps_.Padding = value;
00477                         }
00478                 }
00479 
00480 
00485                 [
00486                 Browsable(false)
00487                 ]
00488                 public Axis XAxis1
00489                 {
00490                         get
00491                         {
00492                                 return ps_.XAxis1;
00493                         }
00494                         set
00495                         {
00496                                 ps_.XAxis1 = value;
00497                         }
00498                 }
00499 
00500 
00504                 [
00505                 Browsable(false)
00506                 ]
00507                 public Axis YAxis1
00508                 {
00509                         get
00510                         {
00511                                 return ps_.YAxis1;
00512                         }
00513                         set
00514                         {
00515                                 ps_.YAxis1 = value;
00516                         }
00517                 }
00518 
00519 
00523                 [
00524                 Browsable(false)
00525                 ]
00526                 public Axis XAxis2
00527                 {
00528                         get
00529                         {
00530                                 return ps_.XAxis2;
00531                         }
00532                         set
00533                         {
00534                                 ps_.XAxis2 = value;
00535                         }
00536                 }
00537 
00538 
00542                 [
00543                 Browsable(false)
00544                 ]
00545                 public Axis YAxis2
00546                 {
00547                         get
00548                         {
00549                                 return ps_.YAxis2;
00550                         }
00551                         set
00552                         {
00553                                 ps_.YAxis2 = value;
00554                         }
00555                 }
00556 
00557 
00561                 [
00562                 Browsable(false)
00563                 ]
00564                 public PhysicalAxis PhysicalXAxis1Cache
00565                 {
00566                         get
00567                         {
00568                                 return ps_.PhysicalXAxis1Cache;
00569                         }
00570                 }
00571 
00572 
00576                 [
00577                 Browsable(false)
00578                 ]
00579                 public PhysicalAxis PhysicalYAxis1Cache
00580                 {
00581                         get
00582                         {
00583                                 return ps_.PhysicalYAxis1Cache;
00584                         }
00585                 }
00586 
00587 
00591                 [
00592                 Browsable(false)
00593                 ]
00594                 public PhysicalAxis PhysicalXAxis2Cache
00595                 {
00596                         get
00597                         {
00598                                 return ps_.PhysicalXAxis2Cache;
00599                         }
00600                 }
00601 
00602 
00606                 [
00607                 Browsable(false)
00608                 ]
00609                 public PhysicalAxis PhysicalYAxis2Cache
00610                 {
00611                         get
00612                         {
00613                                 return ps_.PhysicalYAxis2Cache;
00614                         }
00615                 }
00616 
00617 
00622                 [
00623                 Category("PlotSurface2D"),
00624                 Description("Set the plot background color."),
00625                 Browsable(true),
00626                 Bindable(false)
00627                 ]
00628                 public System.Drawing.Color PlotBackColor
00629                 {
00630                         set
00631                         {
00632                                 ps_.PlotBackColor = value;
00633                         }
00634                 }
00635 
00636 
00641                 [
00642                 Browsable(false),
00643                 Bindable(false)
00644                 ]
00645                 public System.Drawing.Bitmap PlotBackImage
00646                 {
00647                         set
00648                         {
00649                                 ps_.PlotBackImage = value;
00650                         }
00651                 }
00652 
00653 
00658                 [
00659                 Browsable(false),
00660                 Bindable(false)
00661                 ]
00662                 public IRectangleBrush PlotBackBrush
00663                 {
00664                         set
00665                         {
00666                                 ps_.PlotBackBrush = value;
00667                         }
00668                 }
00669 
00670 
00675                 [
00676                 Browsable(false),
00677                 Bindable(false)
00678                 ]
00679                 public Color TitleColor
00680                 {
00681                         set
00682                         {
00683                                 ps_.TitleColor = value;
00684                         }
00685                 }
00686 
00687 
00691                 [
00692                 Browsable(true),
00693                 Bindable(true),
00694                 Description("The brush used for drawing the title."),
00695                 Category("PlotSurface2D")
00696                 ]
00697                 public Brush TitleBrush
00698                 {
00699                         get
00700                         {
00701                                 return ps_.TitleBrush;
00702                         }
00703                         set
00704                         {
00705                                 ps_.TitleBrush = value;
00706                         }
00707                 }
00708 
00709 
00713                 [
00714                 Category("PlotSurface2D"),
00715                 Description("Set smoothing mode for drawing plot objects."),
00716                 Browsable(true),
00717                 Bindable(true)
00718                 ]
00719                 public System.Drawing.Drawing2D.SmoothingMode SmoothingMode 
00720                 { 
00721                         get
00722                         {
00723                                 return ps_.SmoothingMode;
00724                         }
00725                         set
00726                         {
00727                                 ps_.SmoothingMode = value;
00728                         }
00729                 }
00730 
00731 
00736                 protected override void OnMouseDown(MouseEventArgs e)
00737                 {
00738                         DoMouseDown(e);
00739                         base.OnMouseDown(e);
00740                 }
00741 
00742 
00748                 public void DoMouseDown( MouseEventArgs e )
00749                 {
00750             foreach (Interactions.Interaction i in interactions_)
00751             {
00752                 i.DoMouseDown(e,this);
00753             }
00754                 }
00755 
00756     
00761         protected override void OnMouseWheel(MouseEventArgs e)
00762         {
00763             DoMouseWheel(e);
00764             base.OnMouseWheel(e);
00765         }
00766 
00772         public void DoMouseWheel(MouseEventArgs e)
00773         {
00774             foreach (Interactions.Interaction i in interactions_)
00775             {
00776                 i.DoMouseWheel(e, this);
00777             }
00778         }
00779 
00780 
00787                 public void DoMouseMove( MouseEventArgs e, System.Windows.Forms.Control ctr )
00788                 {
00789             foreach (Interactions.Interaction i in interactions_)
00790             {
00791                 i.DoMouseMove(e, ctr, lastKeyEventArgs_);
00792             }
00793 
00794             // Update coordinates if necessary. 
00795 
00796                         if ( coordinates_.Active )
00797                         {
00798                                 // we are here
00799                                 Point here = new Point( e.X, e.Y );
00800                                 if ( ps_.PlotAreaBoundingBoxCache.Contains(here) )
00801                                 {
00802                                         coordinates_.ShowAlways = true;
00803                                         
00804                                         // according to Måns Erlandson, this can sometimes be the case.
00805                                         if (this.PhysicalXAxis1Cache == null)
00806                                                 return;
00807                                         if (this.PhysicalYAxis1Cache == null)
00808                                                 return;
00809 
00810                                         double x = this.PhysicalXAxis1Cache.PhysicalToWorld( here, true );
00811                                         double y = this.PhysicalYAxis1Cache.PhysicalToWorld( here, true );
00812                                         string s = "";
00813                                         if (!DateTimeToolTip)
00814                                         {
00815                                                 s = "(" + x.ToString("g4") + "," + y.ToString("g4") + ")"; 
00816                                         }
00817                                         else
00818                                         {
00819                                                 DateTime dateTime = new DateTime((long)x);
00820                                                 s = dateTime.ToShortDateString() + " " + dateTime.ToLongTimeString() + Environment.NewLine + y.ToString("f4");
00821                                         }
00822                                         coordinates_.SetToolTip( this, s );
00823                                 }
00824                                 else
00825                                 {
00826                                         coordinates_.ShowAlways = false;
00827                                 }
00828                         }
00829 
00830                 }
00831 
00832 
00837                 protected override void OnMouseMove(MouseEventArgs e)
00838                 {
00839                         DoMouseMove( e, this );
00840                         base.OnMouseMove( e );
00841                 }
00842                 
00843 
00848                 [
00849                 Bindable(true),
00850                 Browsable(true),
00851                 Category("PlotSurface2D"),
00852                 Description("When true, tool tip will display x value as a DateTime. Quick hack - this will probably be changed at some point.")
00853                 ]
00854                 public bool DateTimeToolTip
00855                 {
00856                         get
00857                         {
00858                                 return dateTimeToolTip_;
00859                         }
00860                         set
00861                         {
00862                                 dateTimeToolTip_ = value;
00863                         }
00864                 }
00865                 private bool dateTimeToolTip_ = false;
00866 
00867 
00874                 public void DoMouseUp( MouseEventArgs e, System.Windows.Forms.Control ctr )
00875                 {
00876             foreach (Interactions.Interaction i in interactions_)
00877             {
00878                 i.DoMouseUp(e,ctr);
00879             }
00880 
00881             if (e.Button == MouseButtons.Right)
00882             {
00883                 Point here = new Point(e.X, e.Y);
00884                 selectedObjects_ = ps_.HitTest(here);
00885                 if (rightMenu_ != null)
00886                     rightMenu_.Menu.Show(ctr, here);
00887             }
00888   
00889         }
00890 
00891 
00896                 protected override void OnMouseUp( MouseEventArgs e )
00897                 {
00898                         DoMouseUp(e, this);
00899                         base.OnMouseUp(e);
00900                 }
00901 
00902 
00906                 public void OriginalDimensions()
00907                 {
00908                         if ( xAxis1ZoomCache_ != null )
00909                         {
00910                 this.XAxis1 = xAxis1ZoomCache_;
00911                 this.XAxis2 = xAxis2ZoomCache_;
00912                 this.YAxis1 = yAxis1ZoomCache_;
00913                 this.YAxis2 = yAxis2ZoomCache_;
00914 
00915                 xAxis1ZoomCache_ = null;
00916                 xAxis2ZoomCache_ = null;
00917                 yAxis1ZoomCache_ = null;
00918                 yAxis2ZoomCache_ = null;
00919             }                                   
00920                         this.Refresh();
00921                 }
00922 
00923         private void DrawHorizontalSelection(Point start, Point end, System.Windows.Forms.UserControl ctr)
00924         {
00925             // the clipping rectangle in screen coordinates
00926             Rectangle clip = ctr.RectangleToScreen(
00927                 new Rectangle(
00928                 (int)ps_.PlotAreaBoundingBoxCache.X,
00929                 (int)ps_.PlotAreaBoundingBoxCache.Y,
00930                 (int)ps_.PlotAreaBoundingBoxCache.Width,
00931                 (int)ps_.PlotAreaBoundingBoxCache.Height));
00932 
00933             start = ctr.PointToScreen(start);
00934             end = ctr.PointToScreen(end);
00935 
00936             ControlPaint.FillReversibleRectangle(
00937                 new Rectangle((int)Math.Min(start.X,end.X), (int)clip.Y, (int)Math.Abs(end.X-start.X), (int)clip.Height),
00938                 Color.White );
00939 
00940         }
00941 
00942 
00948                 public void AddAxesConstraint( AxesConstraint c )
00949                 {
00950                         ps_.AddAxesConstraint( c );
00951                 }
00952 
00953 
00958                 public void Print( bool preview ) 
00959                 {
00960                         PrintDocument printDocument = new PrintDocument();
00961                         printDocument.PrintPage += new PrintPageEventHandler(NPlot_PrintPage);
00962                         printDocument.DefaultPageSettings.Landscape = true;
00963                                         
00964                         DialogResult result;
00965                         if (!preview) 
00966                         {
00967                                 PrintDialog dlg = new PrintDialog();
00968                                 dlg.Document = printDocument;
00969                                 result = dlg.ShowDialog();
00970                         } 
00971                         else 
00972                         {
00973                                 PrintPreviewDialog dlg = new PrintPreviewDialog();
00974                                 dlg.Document = printDocument;
00975                                 result = dlg.ShowDialog();
00976                         }
00977                         if (result == DialogResult.OK) 
00978                         {
00979                                 try 
00980                                 {
00981                                         printDocument.Print();
00982                                 }                                                                                               
00983                                 catch 
00984                                 {
00985                                         Console.WriteLine( "caught\n" );
00986                                 }
00987                         }
00988                 }
00989 
00990 
00991                 private void NPlot_PrintPage(object sender, PrintPageEventArgs ev) 
00992                 {
00993                         Rectangle r = ev.MarginBounds;
00994                         this.Draw( ev.Graphics, r );
00995                         ev.HasMorePages = false;
00996                 }
00997         
00998                 
01002                 public void CopyToClipboard()
01003                 {
01004                         System.Drawing.Bitmap b = new System.Drawing.Bitmap( this.Width, this.Height );
01005                         System.Drawing.Graphics g = Graphics.FromImage( b );
01006                         g.Clear(Color.White);
01007                         this.Draw( g, new Rectangle( 0, 0, b.Width-1, b.Height-1 ) );
01008                         Clipboard.SetDataObject( b, true );
01009                 }
01010 
01011 
01016                 public void CopyDataToClipboard()
01017                 {
01018 
01019                         System.Text.StringBuilder sb = new System.Text.StringBuilder();
01020 
01021                         for (int i=0; i<ps_.Drawables.Count; ++i)
01022                         {
01023                                 IPlot plot = ps_.Drawables[i] as IPlot;
01024                                 if (plot != null)
01025                                 {
01026                                         Axis xAxis = ps_.WhichXAxis( plot );
01027                                         Axis yAxis = ps_.WhichYAxis( plot );
01028 
01029                                         RectangleD region = new RectangleD( 
01030                                                 xAxis.WorldMin, 
01031                                                 yAxis.WorldMin,
01032                                                 xAxis.WorldMax - xAxis.WorldMin,
01033                                                 yAxis.WorldMax - yAxis.WorldMin );
01034 
01035                                         plot.WriteData( sb, region, true );
01036                                 }
01037                         }
01038 
01039                         Clipboard.SetDataObject( sb.ToString(), true );
01040 
01041                 }
01042 
01043 
01049         public void Remove(IDrawable p, bool updateAxes)
01050         {
01051             ps_.Remove(p, updateAxes);
01052         }
01053 
01054 
01058                 [
01059                 Browsable(false),
01060                 Bindable(false)
01061                 ]
01062                 public ArrayList Drawables
01063                 {
01064                         get
01065                         {
01066                                 return ps_.Drawables;
01067                         }
01068                 }
01069 
01070 
01075                 [
01076                 Browsable(false),
01077                 Bindable(false)
01078                 ]
01079                 public NPlot.Windows.PlotSurface2D.PlotContextMenu RightMenu
01080                 {
01081                         get
01082                         {
01083                                 return rightMenu_;
01084                         }
01085                         set
01086                         {
01087                                 rightMenu_ = value;
01088                                 if (rightMenu_ != null)
01089                                 {
01090                                         rightMenu_.PlotSurface2D = this;
01091                                 }
01092                         }
01093                 }
01094                 private NPlot.Windows.PlotSurface2D.PlotContextMenu rightMenu_ = null;
01095 
01096 
01101                 public static PlotContextMenu DefaultContextMenu
01102                 {
01103                         get
01104                         {
01105                                 return new NPlot.Windows.PlotSurface2D.PlotContextMenu();
01106                         }
01107                 }
01108 
01109 
01113         [
01114                 Browsable(false),
01115                 Bindable(false)
01116                 ]
01117         public NPlot.PlotSurface2D Inner
01118         {
01119             get
01120             {
01121                 return ps_;
01122             }
01123         }
01124 
01125 
01129         public void CacheAxes()
01130         {
01131             if (xAxis1ZoomCache_ == null && xAxis2ZoomCache_ == null &&
01132                  yAxis1ZoomCache_ == null && yAxis2ZoomCache_ == null)
01133             {
01134                 if (this.XAxis1 != null)
01135                 {
01136                     xAxis1ZoomCache_ = (Axis)this.XAxis1.Clone();
01137                 }
01138                 if (this.XAxis2 != null)
01139                 {
01140                     xAxis2ZoomCache_ = (Axis)this.XAxis2.Clone();
01141                 }
01142                 if (this.YAxis1 != null)
01143                 {
01144                     yAxis1ZoomCache_ = (Axis)this.YAxis1.Clone();
01145                 }
01146                 if (this.YAxis2 != null)
01147                 {
01148                     yAxis2ZoomCache_ = (Axis)this.YAxis2.Clone();
01149                 }
01150             }
01151         }
01152 
01153 
01159         public class Interactions
01160         {
01161 
01166             public class Interaction
01167             {
01173                 public virtual void DoMouseDown(MouseEventArgs e, System.Windows.Forms.Control ctr) { }
01174                 
01180                 public virtual void DoMouseUp(MouseEventArgs e, System.Windows.Forms.Control ctr) { }
01181                 
01188                 public virtual void DoMouseMove(MouseEventArgs e, System.Windows.Forms.Control ctr, KeyEventArgs lastKeyEventArgs) { }
01189                 
01195                 public virtual void DoMouseWheel(MouseEventArgs e, System.Windows.Forms.Control ctr) { }
01196                 
01203                 public virtual void DoPaint(PaintEventArgs pe, int width, int height) { }
01204             }
01205 
01206 
01207             #region RubberBandSelection
01211             public class RubberBandSelection : Interaction
01212             {
01213                 private bool selectionInitiated_ = false;
01214 
01220                 public override void DoMouseDown(MouseEventArgs e, Control ctr)
01221                 {
01222                     // keep track of the start point and flag that select initiated.
01223                     selectionInitiated_ = true;
01224                     startPoint_.X = e.X;
01225                     startPoint_.Y = e.Y;
01226 
01227                     // invalidate the end point
01228                     endPoint_ = unset_;
01229                 }
01230 
01237                 public override void DoMouseMove(MouseEventArgs e, Control ctr, KeyEventArgs lastKeyEventArgs)
01238                 {
01239 
01240                     if ((e.Button == MouseButtons.Left) && selectionInitiated_)
01241                     {
01242                         // we are here
01243                         Point here = new Point(e.X, e.Y);
01244 
01245                         // delete the previous box
01246                         if (endPoint_ != unset_)
01247                         {
01248                             this.DrawRubberBand(startPoint_, endPoint_, ctr);
01249                         }
01250                         endPoint_ = here;
01251 
01252                         // and redraw the last one
01253                         this.DrawRubberBand(startPoint_, endPoint_, ctr);
01254 
01255                     }
01256                    
01257                 }
01258 
01264                 public override void DoMouseUp(MouseEventArgs e, Control ctr)
01265                 {
01266 
01267                     NPlot.PlotSurface2D ps = ((Windows.PlotSurface2D)ctr).Inner;
01268 
01269                     // handle left button (selecting region).
01270                     if ((e.Button == MouseButtons.Left) && selectionInitiated_)
01271                     {
01272                         endPoint_.X = e.X;
01273                         endPoint_.Y = e.Y;
01274 
01275                         // flag stopped selecting.
01276                         selectionInitiated_ = false;
01277 
01278                         if (endPoint_ != unset_)
01279                         {
01280                             this.DrawRubberBand(startPoint_, endPoint_, ctr);
01281                         }
01282 
01283                         Point minPoint = new Point(0, 0);
01284                         minPoint.X = Math.Min(startPoint_.X, endPoint_.X);
01285                         minPoint.Y = Math.Min(startPoint_.Y, endPoint_.Y);
01286 
01287                         Point maxPoint = new Point(0, 0);
01288                         maxPoint.X = Math.Max(startPoint_.X, endPoint_.X);
01289                         maxPoint.Y = Math.Max(startPoint_.Y, endPoint_.Y);
01290 
01291                         Rectangle r = ps.PlotAreaBoundingBoxCache;
01292                         if (minPoint != maxPoint && (r.Contains(minPoint) || r.Contains(maxPoint)))
01293                         {
01294                             ((Windows.PlotSurface2D)ctr).CacheAxes();
01295 
01296                             ((Windows.PlotSurface2D)ctr).PhysicalXAxis1Cache.SetWorldLimitsFromPhysical(minPoint, maxPoint);
01297                             ((Windows.PlotSurface2D)ctr).PhysicalXAxis2Cache.SetWorldLimitsFromPhysical(minPoint, maxPoint);
01298                             ((Windows.PlotSurface2D)ctr).PhysicalYAxis1Cache.SetWorldLimitsFromPhysical(maxPoint, minPoint);
01299                             ((Windows.PlotSurface2D)ctr).PhysicalYAxis2Cache.SetWorldLimitsFromPhysical(maxPoint, minPoint);
01300 
01301                             // reset the start/end points
01302                             startPoint_ = unset_;
01303                             endPoint_ = unset_;
01304 
01305                             ((Windows.PlotSurface2D)ctr).InteractionOccured(this);
01306 
01307                             ctr.Refresh();
01308                         }
01309                     }
01310                 }
01311 
01319                 private void DrawRubberBand(Point start, Point end, System.Windows.Forms.Control ctr)
01320                 {
01321                     NPlot.PlotSurface2D ps = ((Windows.PlotSurface2D)ctr).Inner;
01322 
01323                     Rectangle rect = new Rectangle();
01324 
01325                     // the clipping rectangle in screen coordinates
01326                     Rectangle clip = ctr.RectangleToScreen(
01327                         new Rectangle(
01328                         (int)ps.PlotAreaBoundingBoxCache.X,
01329                         (int)ps.PlotAreaBoundingBoxCache.Y,
01330                         (int)ps.PlotAreaBoundingBoxCache.Width,
01331                         (int)ps.PlotAreaBoundingBoxCache.Height));
01332 
01333                     // convert to screen coords
01334                     start = ctr.PointToScreen(start);
01335                     end = ctr.PointToScreen(end);
01336 
01337                     // now, "normalize" the rectangle
01338                     if (start.X < end.X)
01339                     {
01340                         rect.X = start.X;
01341                         rect.Width = end.X - start.X;
01342                     }
01343                     else
01344                     {
01345                         rect.X = end.X;
01346                         rect.Width = start.X - end.X;
01347                     }
01348                     if (start.Y < end.Y)
01349                     {
01350                         rect.Y = start.Y;
01351                         rect.Height = end.Y - start.Y;
01352                     }
01353                     else
01354                     {
01355                         rect.Y = end.Y;
01356                         rect.Height = start.Y - end.Y;
01357                     }
01358                     rect = Rectangle.Intersect(rect, clip);
01359 
01360                     ControlPaint.DrawReversibleFrame(
01361                         new Rectangle((int)rect.X, (int)rect.Y, (int)rect.Width, (int)rect.Height),
01362                         Color.White, FrameStyle.Dashed);
01363 
01364                 }
01365 
01366                 private Point startPoint_ = new Point(-1, -1);
01367                 private Point endPoint_ = new Point(-1, -1);
01368                 // this is the condition for an unset point
01369                 private Point unset_ = new Point(-1, -1);
01370 
01371             }
01372             #endregion
01373             #region HorizontalGuideline
01377             public class HorizontalGuideline : Interaction
01378             {
01379                 private int barPos_;
01380                 private Color color_;
01381 
01385                 public HorizontalGuideline()
01386                 {
01387                     color_ = Color.Black;
01388                 }
01389 
01394                 public HorizontalGuideline(Color lineColor)
01395                 {
01396                     color_ = lineColor;
01397                 }
01398 
01405                 public override void DoPaint(PaintEventArgs pe, int width, int height)
01406                 {
01407                     barPos_ = -1;
01408                 }
01409 
01416                 public override void DoMouseMove(MouseEventArgs e, System.Windows.Forms.Control ctr, KeyEventArgs lastKeyEventArgs)
01417                 {
01418 
01419                     NPlot.PlotSurface2D ps = ((Windows.PlotSurface2D)ctr).Inner;
01420 
01421                     // if mouse isn't in plot region, then don't draw horizontal line
01422                     if (e.X > ps.PlotAreaBoundingBoxCache.Left && e.X < ps.PlotAreaBoundingBoxCache.Right &&
01423                         e.Y > ps.PlotAreaBoundingBoxCache.Top && e.Y < (ps.PlotAreaBoundingBoxCache.Bottom-1))
01424                     {
01425 
01426                         if (ps.PhysicalXAxis1Cache != null)
01427                         {
01428 
01429                             // the clipping rectangle in screen coordinates
01430                             Rectangle clip = ctr.RectangleToScreen(
01431                                 new Rectangle(
01432                                 (int)ps.PlotAreaBoundingBoxCache.X,
01433                                 (int)ps.PlotAreaBoundingBoxCache.Y,
01434                                 (int)ps.PlotAreaBoundingBoxCache.Width,
01435                                 (int)ps.PlotAreaBoundingBoxCache.Height));
01436 
01437                             Point p = ctr.PointToScreen(new Point(e.X, e.Y));
01438 
01439                             if (barPos_ != -1)
01440                             {
01441                                 ControlPaint.DrawReversibleLine(
01442                                     new Point(clip.Left, barPos_),
01443                                     new Point(clip.Right, barPos_), color_);
01444                             }
01445 
01446                             if (p.Y < clip.Bottom && p.Y > clip.Top)
01447                             {
01448                                 ControlPaint.DrawReversibleLine(
01449                                     new Point(clip.Left, p.Y),
01450                                     new Point(clip.Right, p.Y), color_);
01451 
01452                                 barPos_ = p.Y;
01453                             }
01454                             else
01455                             {
01456                                 barPos_ = -1;
01457                             }
01458 
01459                         }
01460 
01461                     }
01462                     else
01463                     {
01464 
01465                         if (barPos_ != -1)
01466                         {
01467                             Rectangle clip = ctr.RectangleToScreen(
01468                                 new Rectangle(
01469                                 (int)ps.PlotAreaBoundingBoxCache.X,
01470                                 (int)ps.PlotAreaBoundingBoxCache.Y,
01471                                 (int)ps.PlotAreaBoundingBoxCache.Width,
01472                                 (int)ps.PlotAreaBoundingBoxCache.Height) );
01473 
01474                             ControlPaint.DrawReversibleLine(
01475                                 new Point(clip.Left, barPos_),
01476                                 new Point(clip.Right, barPos_), color_);
01477                             barPos_ = -1;
01478                         }
01479 
01480                         //ctr.Refresh();
01481                     }
01482                 }
01483             }
01484             #endregion
01485             #region VerticalGuideline
01489             public class VerticalGuideline : Interaction
01490             {
01491                 private int barPos_;
01492                 private Color color_;
01493 
01497                 public VerticalGuideline()
01498                 {
01499                     color_ = Color.Black;
01500                 }
01501 
01506                 public VerticalGuideline(Color lineColor)
01507                 {
01508                     color_ = lineColor;
01509                 }
01510 
01517                 public override void DoPaint(PaintEventArgs pe, int width, int height)
01518                 {
01519                     barPos_ = -1;
01520                 }
01521 
01528                 public override void DoMouseMove(MouseEventArgs e, System.Windows.Forms.Control ctr, KeyEventArgs lastKeyEventArgs)
01529                 {
01530                     NPlot.PlotSurface2D ps = ((Windows.PlotSurface2D)ctr).Inner;
01531 
01532                     // if mouse isn't in plot region, then don't draw horizontal line
01533                     if (e.X > ps.PlotAreaBoundingBoxCache.Left && e.X < (ps.PlotAreaBoundingBoxCache.Right-1) &&
01534                         e.Y > ps.PlotAreaBoundingBoxCache.Top && e.Y < ps.PlotAreaBoundingBoxCache.Bottom)
01535                     {
01536                         if (ps.PhysicalXAxis1Cache != null)
01537                         {
01538 
01539                             // the clipping rectangle in screen coordinates
01540                             Rectangle clip = ctr.RectangleToScreen(
01541                                 new Rectangle(
01542                                 (int)ps.PlotAreaBoundingBoxCache.X,
01543                                 (int)ps.PlotAreaBoundingBoxCache.Y,
01544                                 (int)ps.PlotAreaBoundingBoxCache.Width,
01545                                 (int)ps.PlotAreaBoundingBoxCache.Height));
01546 
01547                             Point p = ctr.PointToScreen(new Point(e.X, e.Y));
01548 
01549                             if (barPos_ != -1)
01550                             {
01551                                 ControlPaint.DrawReversibleLine(
01552                                     new Point(barPos_, clip.Top),
01553                                     new Point(barPos_, clip.Bottom), color_);
01554                             }
01555 
01556                             if (p.X < clip.Right && p.X > clip.Left)
01557                             {
01558                                 ControlPaint.DrawReversibleLine(
01559                                     new Point(p.X, clip.Top),
01560                                     new Point(p.X, clip.Bottom), color_);
01561                                 barPos_ = p.X;
01562                             }
01563                             else
01564                             {
01565                                 barPos_ = -1;
01566                             }
01567 
01568                         }
01569 
01570                     }
01571                     else
01572                     {
01573                         
01574                         Rectangle clip = ctr.RectangleToScreen(
01575                             new Rectangle(
01576                             (int)ps.PlotAreaBoundingBoxCache.X,
01577                             (int)ps.PlotAreaBoundingBoxCache.Y,
01578                             (int)ps.PlotAreaBoundingBoxCache.Width,
01579                             (int)ps.PlotAreaBoundingBoxCache.Height));
01580 
01581                         if (barPos_ != -1)
01582                         {
01583                             ControlPaint.DrawReversibleLine(
01584                                 new Point(barPos_, clip.Top),
01585                                 new Point(barPos_, clip.Bottom), color_);
01586                             barPos_ = -1;
01587                         }
01588 
01589                         // this stuffs up other interactions
01590                         //ctr.Refresh();
01591 
01592                     }
01593 
01594                 }
01595 
01596             }
01597             #endregion
01598             #region HorizontalDrag
01602             public class HorizontalDrag : Interaction
01603             {
01604 
01610                 public override void DoMouseDown(MouseEventArgs e, Control ctr)
01611                 {
01612                     NPlot.PlotSurface2D ps = ((Windows.PlotSurface2D)ctr).Inner;
01613 
01614                     if (e.X > ps.PlotAreaBoundingBoxCache.Left && e.X < (ps.PlotAreaBoundingBoxCache.Right) &&
01615                         e.Y > ps.PlotAreaBoundingBoxCache.Top && e.Y < ps.PlotAreaBoundingBoxCache.Bottom)
01616                     {
01617                         dragInitiated_ = true;
01618 
01619                         lastPoint_.X = e.X;
01620                         lastPoint_.Y = e.Y;
01621                     }
01622                 }
01623 
01630                 public override void DoMouseMove(MouseEventArgs e, Control ctr, KeyEventArgs lastKeyEventArgs)
01631                 {
01632                     NPlot.PlotSurface2D ps = ((Windows.PlotSurface2D)ctr).Inner;
01633 
01634 
01635                     if ((e.Button == MouseButtons.Left) && dragInitiated_)
01636                     {
01637                             int diffX = e.X - lastPoint_.X;
01638                             int diffY = 0;
01639 
01640                             ((Windows.PlotSurface2D)ctr).CacheAxes();
01641 
01642                             if (ps.XAxis1 != null)
01643                             {
01644                                 ps.XAxis1.WorldMin -= ps.PhysicalXAxis1Cache.PixelWorldLength * diffX;
01645                                 ps.XAxis1.WorldMax -= ps.PhysicalXAxis1Cache.PixelWorldLength * diffX;
01646                             }
01647                             if (ps.XAxis2 != null)
01648                             {
01649                                 ps.XAxis2.WorldMin -= ps.PhysicalXAxis2Cache.PixelWorldLength * diffX;
01650                                 ps.XAxis2.WorldMax -= ps.PhysicalXAxis2Cache.PixelWorldLength * diffX;
01651                             }
01652                             if (ps.YAxis1 != null)
01653                             {
01654                                 ps.YAxis1.WorldMin += ps.PhysicalYAxis1Cache.PixelWorldLength * diffY;
01655                                 ps.YAxis1.WorldMax += ps.PhysicalYAxis1Cache.PixelWorldLength * diffY;
01656                             }
01657                             if (ps.YAxis2 != null)
01658                             {
01659                                 ps.YAxis2.WorldMin += ps.PhysicalYAxis2Cache.PixelWorldLength * diffY;
01660                                 ps.YAxis2.WorldMax += ps.PhysicalYAxis2Cache.PixelWorldLength * diffY;
01661                             }
01662 
01663                             lastPoint_ = new Point(e.X, e.Y);
01664 
01665                             ((Windows.PlotSurface2D)ctr).InteractionOccured(this);
01666 
01667                             ctr.Refresh();
01668                         }
01669                     
01670                 }
01671 
01677                 public override void DoMouseUp(MouseEventArgs e, Control ctr)
01678                 {
01679                    if ((e.Button == MouseButtons.Left) && dragInitiated_)
01680                    {
01681                       lastPoint_ = unset_;
01682                       dragInitiated_ = false;
01683                    }
01684                 }
01685 
01686                 private bool dragInitiated_ = false;
01687                 private Point lastPoint_ = new Point(-1, -1);
01688                 // this is the condition for an unset point
01689                 private Point unset_ = new Point(-1, -1);
01690             }
01691             #endregion
01692             #region VerticalDrag
01696             public class VerticalDrag : Interaction
01697             {
01703                 public override void DoMouseDown(MouseEventArgs e, Control ctr)
01704                 {
01705                     NPlot.PlotSurface2D ps = ((Windows.PlotSurface2D)ctr).Inner;
01706 
01707                     if (e.X > ps.PlotAreaBoundingBoxCache.Left && e.X < (ps.PlotAreaBoundingBoxCache.Right) &&
01708                         e.Y > ps.PlotAreaBoundingBoxCache.Top && e.Y < ps.PlotAreaBoundingBoxCache.Bottom)
01709                     {
01710                         dragInitiated_ = true;
01711 
01712                         lastPoint_.X = e.X;
01713                         lastPoint_.Y = e.Y;
01714                     }
01715                 }
01716 
01717 
01724                 public override void DoMouseMove(MouseEventArgs e, Control ctr, KeyEventArgs lastKeyEventArgs)
01725                 {
01726                     NPlot.PlotSurface2D ps = ((Windows.PlotSurface2D)ctr).Inner;
01727 
01728                     if ((e.Button == MouseButtons.Left) && dragInitiated_)
01729                     {
01730   
01731                             int diffY = e.Y - lastPoint_.Y;
01732                             int diffX = 0;
01733 
01734                             ((Windows.PlotSurface2D)ctr).CacheAxes();
01735 
01736                             if (ps.XAxis1 != null)
01737                             {
01738                                 ps.XAxis1.WorldMin -= ps.PhysicalXAxis1Cache.PixelWorldLength * diffX;
01739                                 ps.XAxis1.WorldMax -= ps.PhysicalXAxis1Cache.PixelWorldLength * diffX;
01740                             }
01741                             if (ps.XAxis2 != null)
01742                             {
01743                                 ps.XAxis2.WorldMin -= ps.PhysicalXAxis2Cache.PixelWorldLength * diffX;
01744                                 ps.XAxis2.WorldMax -= ps.PhysicalXAxis2Cache.PixelWorldLength * diffX;
01745                             }
01746                             if (ps.YAxis1 != null)
01747                             {
01748                                 ps.YAxis1.WorldMin += ps.PhysicalYAxis1Cache.PixelWorldLength * diffY;
01749                                 ps.YAxis1.WorldMax += ps.PhysicalYAxis1Cache.PixelWorldLength * diffY;
01750                             }
01751                             if (ps.YAxis2 != null)
01752                             {
01753                                 ps.YAxis2.WorldMin += ps.PhysicalYAxis2Cache.PixelWorldLength * diffY;
01754                                 ps.YAxis2.WorldMax += ps.PhysicalYAxis2Cache.PixelWorldLength * diffY;
01755                             }
01756 
01757                             lastPoint_ = new Point(e.X, e.Y);
01758 
01759                             ((Windows.PlotSurface2D)ctr).InteractionOccured(this);
01760 
01761                             ctr.Refresh();
01762                         }
01763                     
01764                 }
01765 
01766 
01772                 public override void DoMouseUp(MouseEventArgs e, Control ctr)
01773                 {
01774                     if ((e.Button == MouseButtons.Left) && dragInitiated_)
01775                     {
01776                         lastPoint_ = unset_;
01777                         dragInitiated_ = false;
01778                     }
01779                 }
01780 
01781                 private bool dragInitiated_ = false;
01782                 private Point lastPoint_ = new Point(-1, -1);
01783                 // this is the condition for an unset point
01784                 private Point unset_ = new Point(-1, -1);
01785             }
01786             #endregion
01787             #region HorizontalRangeSelection
01791             public class HorizontalRangeSelection : Interaction
01792             {
01793                 private bool selectionInitiated_ = false;
01794                 private Point startPoint_ = new Point(-1, -1);
01795                 private Point endPoint_ = new Point(-1, -1);
01796                 private Point previousPoint_ = new Point(-1, -1);
01797                 private Point unset_ = new Point(-1, -1);
01798 
01804                 public override void DoMouseDown(MouseEventArgs e, Control ctr )
01805                 {
01806                     NPlot.PlotSurface2D ps = ((Windows.PlotSurface2D)ctr).Inner;
01807 
01808                     if (e.X > ps.PlotAreaBoundingBoxCache.Left && e.X < ps.PlotAreaBoundingBoxCache.Right &&
01809                         e.Y > ps.PlotAreaBoundingBoxCache.Top && e.Y < ps.PlotAreaBoundingBoxCache.Bottom)
01810                     {
01811 
01812                         // keep track of the start point and flag that select initiated.
01813                         selectionInitiated_ = true;
01814                         startPoint_.X = e.X;
01815                         startPoint_.Y = e.Y;
01816 
01817                         previousPoint_.X = e.X;
01818                         previousPoint_.Y = e.Y;
01819 
01820                         // invalidate the end point
01821                         endPoint_ = unset_;
01822 
01823                         return;
01824                     }
01825 
01826                     selectionInitiated_ = false;
01827                     endPoint_ = unset_;
01828                     startPoint_ = unset_;
01829                 }
01830 
01831                 
01838                 public override void DoMouseMove(MouseEventArgs e, Control ctr, KeyEventArgs lastKeyEventArgs)
01839                 {
01840                     NPlot.PlotSurface2D ps = ((Windows.PlotSurface2D)ctr).Inner;
01841 
01842                     // if dragging on axis to zoom.
01843                     if ((e.Button == MouseButtons.Left) && selectionInitiated_)
01844                     {
01845                         Point endPoint_ = previousPoint_;
01846                         if (e.X > ps.PlotAreaBoundingBoxCache.Left && e.X < ps.PlotAreaBoundingBoxCache.Right &&
01847                             e.Y > ps.PlotAreaBoundingBoxCache.Top && e.Y < ps.PlotAreaBoundingBoxCache.Bottom)
01848                         {
01849                             endPoint_ = new Point(e.X, e.Y);
01850                             this.DrawHorizontalSelection(previousPoint_, endPoint_, ctr);
01851                             previousPoint_ = endPoint_;
01852                         }
01853                         else
01854                         {
01855                             endPoint_ = new Point(e.X, e.Y);
01856                             if (e.X < ps.PlotAreaBoundingBoxCache.Left) endPoint_.X = ps.PlotAreaBoundingBoxCache.Left + 1;
01857                             if (e.X > ps.PlotAreaBoundingBoxCache.Right) endPoint_.X = ps.PlotAreaBoundingBoxCache.Right - 1;
01858                             this.DrawHorizontalSelection(previousPoint_, endPoint_, ctr);
01859                             previousPoint_ = endPoint_;
01860                         }
01861                     }
01862 
01863                 }
01864 
01865                 
01871                 public override void DoMouseUp(MouseEventArgs e, Control ctr)
01872                 {
01873                     NPlot.PlotSurface2D ps = ((Windows.PlotSurface2D)ctr).Inner;
01874 
01875 
01876                     if ((e.Button == MouseButtons.Left) && selectionInitiated_)
01877                     {
01878                         endPoint_.X = e.X;
01879                         endPoint_.Y = e.Y;
01880                         if (e.X < ps.PlotAreaBoundingBoxCache.Left) endPoint_.X = ps.PlotAreaBoundingBoxCache.Left + 1;
01881                         if (e.X > ps.PlotAreaBoundingBoxCache.Right) endPoint_.X = ps.PlotAreaBoundingBoxCache.Right - 1;
01882 
01883                         // flag stopped selecting.
01884                         selectionInitiated_ = false;
01885 
01886                         if (endPoint_ != unset_)
01887                         {
01888                             this.DrawHorizontalSelection(startPoint_, endPoint_, ctr);
01889                         }
01890 
01891                         ((Windows.PlotSurface2D)ctr).CacheAxes();
01892 
01893                         if (ps.XAxis1 != null)
01894                         {
01895                             int x1 = (int)Math.Min(endPoint_.X, startPoint_.X);
01896                             int x2 = (int)Math.Max(endPoint_.X, startPoint_.X);
01897                             int y = ps.PhysicalXAxis1Cache.PhysicalMax.Y;
01898 
01899                             double min = ps.PhysicalXAxis1Cache.PhysicalToWorld(new Point(x1, y), true);
01900                             ps.XAxis1.WorldMax = ps.PhysicalXAxis1Cache.PhysicalToWorld(new Point(x2, y), true);
01901                             ps.XAxis1.WorldMin = min;
01902                         }
01903 
01904                         if (ps.XAxis2 != null)
01905                         {
01906                             int x1 = (int)Math.Min(endPoint_.X, startPoint_.X);
01907                             int x2 = (int)Math.Max(endPoint_.X, startPoint_.X);
01908                             int y = ps.PhysicalXAxis2Cache.PhysicalMax.Y;
01909 
01910                             double min = ps.PhysicalXAxis2Cache.PhysicalToWorld(new Point(x1, y), true);
01911                             ps.XAxis2.WorldMax = ps.PhysicalXAxis2Cache.PhysicalToWorld(new Point(x2, y), true);
01912                             ps.XAxis2.WorldMin = min;
01913                         }
01914 
01915                         ((Windows.PlotSurface2D)ctr).InteractionOccured(this);
01916 
01917                         ctr.Refresh();
01918                     }
01919                 }
01920 
01921                 private void DrawHorizontalSelection(Point start, Point end, System.Windows.Forms.Control ctr)
01922                 {
01923                     NPlot.PlotSurface2D ps = ((Windows.PlotSurface2D)ctr).Inner;
01924 
01925                     // the clipping rectangle in screen coordinates
01926                     Rectangle clip = ctr.RectangleToScreen(
01927                         new Rectangle(
01928                         (int)ps.PlotAreaBoundingBoxCache.X,
01929                         (int)ps.PlotAreaBoundingBoxCache.Y,
01930                         (int)ps.PlotAreaBoundingBoxCache.Width,
01931                         (int)ps.PlotAreaBoundingBoxCache.Height));
01932 
01933                     start = ctr.PointToScreen(start);
01934                     end = ctr.PointToScreen(end);
01935 
01936                     ControlPaint.FillReversibleRectangle(
01937                         new Rectangle((int)Math.Min(start.X, end.X), (int)clip.Y, (int)Math.Abs(end.X - start.X), (int)clip.Height),
01938                         Color.White);
01939 
01940                 }
01941 
01942             }
01943             #endregion
01944             #region AxisDrag
01948             public class AxisDrag : Interaction
01949             {
01950 
01955                 public AxisDrag(bool enableDragWithCtr)
01956                 {
01957                     enableDragWithCtr_ = enableDragWithCtr;
01958                 }
01959 
01960                 private bool enableDragWithCtr_ = false;
01961 
01962                 private Axis axis_ = null;
01963                 private bool doing_ = false;
01964                 private Point lastPoint_ = new Point();
01965                 private PhysicalAxis physicalAxis_ = null;
01966                 private Point startPoint_ = new Point();
01967 
01968 
01974                 public override void DoMouseDown(MouseEventArgs e, Control ctr)
01975                 {
01976                     // if the mouse is inside the plot area [the tick marks are here and part of the 
01977                     // axis], then don't invoke drag. 
01978                     NPlot.PlotSurface2D ps = ((Windows.PlotSurface2D)ctr).Inner;
01979                     if (e.X > ps.PlotAreaBoundingBoxCache.Left && e.X < ps.PlotAreaBoundingBoxCache.Right &&
01980                         e.Y > ps.PlotAreaBoundingBoxCache.Top && e.Y < ps.PlotAreaBoundingBoxCache.Bottom)
01981                     {
01982                         return;
01983                     }
01984 
01985                     if ((e.Button == MouseButtons.Left))
01986                     {
01987                         // see if hit with axis.
01988                         ArrayList objects = ps.HitTest(new Point(e.X, e.Y));
01989 
01990                         foreach (object o in objects)
01991                         {
01992                             if (o is NPlot.Axis)
01993                             {
01994                                 doing_ = true;
01995                                 axis_ = (Axis)o;
01996 
01997                                 PhysicalAxis[] physicalAxisList = new PhysicalAxis[] { ps.PhysicalXAxis1Cache, ps.PhysicalXAxis2Cache, ps.PhysicalYAxis1Cache, ps.PhysicalYAxis2Cache };
01998 
01999                                 if (ps.PhysicalXAxis1Cache.Axis == axis_)
02000                                     physicalAxis_ = ps.PhysicalXAxis1Cache;
02001                                 else if (ps.PhysicalXAxis2Cache.Axis == axis_)
02002                                     physicalAxis_ = ps.PhysicalXAxis2Cache;
02003                                 else if (ps.PhysicalYAxis1Cache.Axis == axis_)
02004                                     physicalAxis_ = ps.PhysicalYAxis1Cache;
02005                                 else if (ps.PhysicalYAxis2Cache.Axis == axis_)
02006                                     physicalAxis_ = ps.PhysicalYAxis2Cache;
02007 
02008                                 lastPoint_ = startPoint_ = new Point(e.X, e.Y);
02009 
02010                                 return;
02011                             }
02012                         }
02013 
02014                     }
02015 
02016                 }
02017 
02018 
02025                 public override void DoMouseMove(MouseEventArgs e, Control ctr, KeyEventArgs lastKeyEventArgs)
02026                 {
02027                     NPlot.PlotSurface2D ps = ((Windows.PlotSurface2D)ctr).Inner;
02028 
02029                     // if dragging on axis to zoom.
02030                     if ((e.Button == MouseButtons.Left) && doing_)
02031                     {
02032                         if (enableDragWithCtr_ && lastKeyEventArgs != null && lastKeyEventArgs.Control)
02033                         {
02034                         }
02035                         else
02036                         {
02037                             float dist =
02038                                 (e.X - lastPoint_.X) +
02039                                 (-e.Y + lastPoint_.Y);
02040 
02041                             lastPoint_ = new Point(e.X, e.Y);
02042 
02043                             if (dist > sensitivity_ / 3.0f)
02044                             {
02045                                 dist = sensitivity_ / 3.0f;
02046                             }
02047 
02048                             double prop = this.axis_.WorldLength * (float)dist / sensitivity_;
02049                             prop *= 2;
02050 
02051                             ((Windows.PlotSurface2D)ctr).CacheAxes();
02052 
02053                             double pos = physicalAxis_.PhysicalToWorld(startPoint_, true);
02054                             double relativePos = (pos - axis_.WorldMin) / axis_.WorldLength;
02055 
02056                             this.axis_.WorldMin += relativePos * prop;
02057                             this.axis_.WorldMax -= (1 - relativePos) * prop;
02058 
02059                             /*
02060                             this.axis_.WorldMin += prop;
02061                             this.axis_.WorldMax -= prop;
02062                             */
02063 
02064                             ((Windows.PlotSurface2D)ctr).InteractionOccured(this);
02065                             ctr.Refresh();
02066                         }
02067                     }
02068 
02069                 }
02070 
02071 
02077                 public override void DoMouseUp(MouseEventArgs e, Control ctr)
02078                 {
02079                     if (doing_)
02080                     {
02081                         doing_ = false;
02082                         axis_ = null;
02083                         lastPoint_ = new Point();
02084                     }
02085                 }
02086 
02087                 private float sensitivity_ = 200.0f;
02088                 
02093                 public float Sensitivity
02094                 {
02095                     get
02096                     {
02097                         return sensitivity_;
02098                     }
02099                     set
02100                     {
02101                         sensitivity_ = value;
02102                     }
02103                 }
02104 
02105             }
02106             #endregion
02107             #region MouseWheelZoom
02111             public class MouseWheelZoom : Interaction
02112             {
02113 
02114                 private Point point_ = new Point(-1, -1);
02115                 //private bool mouseDown_ = false;
02116 
02122                 public override void DoMouseUp(MouseEventArgs e, Control ctr)
02123                 {
02124                     //mouseDown_ = false;
02125                 }
02126 
02132                 public override void DoMouseDown(MouseEventArgs e, Control ctr)
02133                 {
02134                     //NPlot.PlotSurface2D ps = ((Windows.PlotSurface2D)ctr).Inner;
02135 
02136                     //if (e.X > ps.PlotAreaBoundingBoxCache.Left && e.X < ps.PlotAreaBoundingBoxCache.Right &&
02137                     //    e.Y > ps.PlotAreaBoundingBoxCache.Top && e.Y < ps.PlotAreaBoundingBoxCache.Bottom)
02138                     //{
02139                     //    point_.X = e.X;
02140                     //    point_.Y = e.Y;
02141                     //    mouseDown_ = true;
02142                     //}
02143                 }
02144 
02150                 public override void DoMouseWheel(MouseEventArgs e, Control ctr)
02151                 {
02152                     //if (true || mouseDown_)
02153                     {
02154                         NPlot.PlotSurface2D ps = ((Windows.PlotSurface2D)ctr).Inner;
02155 
02156                         ((Windows.PlotSurface2D)ctr).CacheAxes();
02157 
02158                         int delta = e.Delta;
02159 
02160                         if (ps.XAxis1 != null)
02161                         {
02162                             ps.XAxis1.WorldMax *= 0.96;
02163                             ps.XAxis1.WorldMin *= 0.96;
02164                         }
02165 
02166                         ((Windows.PlotSurface2D)ctr).InteractionOccured(this);
02167                         ctr.Refresh();
02168                     }
02169                 }
02170 
02171             }
02172             #endregion
02173 
02174         }
02175 
02176         private ArrayList interactions_ = new ArrayList();
02177 
02178 
02184         public void AddInteraction(Interactions.Interaction i)
02185         {
02186             interactions_.Add(i);
02187         }
02188 
02189 
02194                 public void RemoveInteraction(Interactions.Interaction i)             
02195                 {
02196                         interactions_.Remove(i);
02197                 }
02198 
02199 
02206         public delegate void InteractionHandler(object sender);
02207         
02208 
02212         public event InteractionHandler InteractionOccured;
02213 
02220         protected void OnInteractionOccured(object sender)
02221         {
02222             // do nothing.
02223         }
02224 
02229         public delegate void PreRefreshHandler(object sender);
02230 
02231 
02235         public event PreRefreshHandler PreRefresh;
02236 
02237 
02242         protected void OnPreRefresh(object sender)
02243         {
02244             // do nothing.
02245         }
02246 
02247 
02248                 #region class PlotContextMenu
02252                 public class PlotContextMenu
02253                 {
02254 
02255                         #region IPlotMenuItem
02259                         public interface IPlotMenuItem
02260                         {
02264                                 System.Windows.Forms.MenuItem MenuItem { get; }
02265 
02272                                 void OnPopup( PlotContextMenu plotContextMenu );
02273                         }
02274                         #endregion
02275                         #region PlotMenuSeparator
02279                         public class PlotMenuSeparator : IPlotMenuItem
02280                         {
02281 
02286                                 public PlotMenuSeparator( int index )
02287                                 {
02288                                         menuItem_ = new System.Windows.Forms.MenuItem();
02289                                         index_ = index;
02290 
02291                                         menuItem_.Index = index_;
02292                                         menuItem_.Text = "-";
02293                                 }
02294 
02295                                 private int index_;
02296 
02300                                 public int Index
02301                                 {
02302                                         get
02303                                         {
02304                                                 return index_;
02305                                         }
02306                                 }
02307 
02308                                 private System.Windows.Forms.MenuItem menuItem_;
02312                                 public System.Windows.Forms.MenuItem MenuItem
02313                                 {
02314                                         get
02315                                         {
02316                                                 return menuItem_;
02317                                         }
02318                                 }
02319 
02324                                 public void OnPopup( PlotContextMenu plotContextMenu )
02325                                 {
02326                                         // do nothing.
02327                                 }
02328 
02329                         }
02330                         #endregion
02331                         #region PlotMenuItem
02335                         public class PlotMenuItem : IPlotMenuItem
02336                         {
02337 
02344                                 public PlotMenuItem( string text, int index, EventHandler callback )
02345                                 {
02346                                         text_ = text;
02347                                         index_ = index;
02348                                         callback_ = callback;
02349 
02350                                         menuItem_ = new System.Windows.Forms.MenuItem();
02351                                         
02352                                         menuItem_.Index = index;
02353                                         menuItem_.Text = text;
02354                                         menuItem_.Click += new System.EventHandler(callback);
02355 
02356                                 }
02357 
02358                                 private string text_;
02362                                 public string Text
02363                                 {
02364                                         get
02365                                         {
02366                                                 return text_;
02367                                         }
02368                                 }
02369 
02370                                 private int index_;
02374                                 public int Index
02375                                 {
02376                                         get
02377                                         {
02378                                                 return index_;
02379                                         }
02380                                 }
02381 
02382                                 private EventHandler callback_;
02386                                 public EventHandler Callback
02387                                 {
02388                                         get
02389                                         {
02390                                                 return callback_;
02391                                         }
02392                                 }
02393 
02394                                 private System.Windows.Forms.MenuItem menuItem_;
02398                                 public System.Windows.Forms.MenuItem MenuItem
02399                                 {
02400                                         get
02401                                         {
02402                                                 return menuItem_;
02403                                         }
02404                                 }
02405 
02410                                 public virtual void OnPopup( PlotContextMenu plotContextMenu )
02411                                 {
02412                                         // do nothing.
02413                                 }
02414 
02415                         }
02416                         #endregion
02417                         #region PlotZoomBackMenuItem
02423                         public class PlotZoomBackMenuItem : PlotMenuItem
02424                         {
02425 
02432                                 public PlotZoomBackMenuItem( string text, int index, EventHandler callback )
02433                                         : base( text, index, callback )
02434                                 {
02435                                 }
02436 
02441                                 public override void OnPopup( PlotContextMenu plotContextMenu )
02442                                 {
02443                                         this.MenuItem.Enabled = plotContextMenu.plotSurface2D_.xAxis1ZoomCache_ != null;
02444                                 }
02445 
02446                         }
02447                         #endregion
02448                         #region PlotShowCoordinatesMenuItem
02454                         public class PlotShowCoordinatesMenuItem : PlotMenuItem
02455                         {
02456 
02463                                 public PlotShowCoordinatesMenuItem( string text, int index, EventHandler callback )
02464                                         : base( text, index, callback )
02465                                 {
02466                                 }
02467 
02472                                 public override void OnPopup( PlotContextMenu plotContextMenu )
02473                                 {
02474                                         this.MenuItem.Checked = plotContextMenu.plotSurface2D_.ShowCoordinates;
02475                                 }
02476                         }
02477                         #endregion
02478 
02479                         private System.Windows.Forms.ContextMenu rightMenu_ = null;
02480                         private ArrayList menuItems_ = null;
02481 
02482 
02488                         public ArrayList MenuItems
02489                         {
02490                                 get
02491                                 {
02492                                         return menuItems_;
02493                                 }
02494                         }
02495 
02500                         public Windows.PlotSurface2D PlotSurface2D
02501                         {
02502                                 set
02503                                 {
02504                                         this.plotSurface2D_ = value;
02505                                 }
02506                         }
02507 
02512                         protected Windows.PlotSurface2D plotSurface2D_;
02513 
02514                         
02521                         public void SetMenuItems(ArrayList menuItems)
02522                         {
02523                                 this.menuItems_ = menuItems;
02524 
02525                                 this.rightMenu_ = new System.Windows.Forms.ContextMenu();
02526                         
02527                                 foreach (IPlotMenuItem item in menuItems_)
02528                                 {
02529                                         this.rightMenu_.MenuItems.Add( item.MenuItem );
02530                                 }
02531 
02532                                 this.rightMenu_.Popup += new System.EventHandler(this.rightMenu__Popup);
02533                         }
02534 
02535 
02539                         public PlotContextMenu()
02540                         {
02541                                 ArrayList menuItems = new ArrayList();
02542 
02543                                 menuItems = new ArrayList();
02544                                 menuItems.Add( new PlotZoomBackMenuItem( "Original Dimensions", 0, new EventHandler(this.mnuOriginalDimensions_Click) ) );
02545                                 menuItems.Add( new PlotShowCoordinatesMenuItem( "Show World Coordinates", 1, new EventHandler(this.mnuDisplayCoordinates_Click) ) ); 
02546                                 menuItems.Add( new PlotMenuSeparator(2) );
02547                                 menuItems.Add( new PlotMenuItem( "Print", 3, new EventHandler(this.mnuPrint_Click )) );
02548                                 menuItems.Add( new PlotMenuItem( "Print Preview", 4, new EventHandler(this.mnuPrintPreview_Click) ) );
02549                                 menuItems.Add( new PlotMenuItem( "Copy To Clipboard", 5, new EventHandler(this.mnuCopyToClipboard_Click) ) );
02550                                 menuItems.Add( new PlotMenuItem( "Copy Data To Clipboard", 6, new EventHandler(this.mnuCopyDataToClipboard_Click) ) );
02551 
02552                                 this.SetMenuItems( menuItems );
02553                         }
02554 
02555 
02556                         private void mnuOriginalDimensions_Click(object sender, System.EventArgs e)
02557                         {
02558                                 plotSurface2D_.OriginalDimensions();
02559                         }
02560 
02561                         private void mnuCopyToClipboard_Click(object sender, System.EventArgs e) 
02562                         {
02563                                 plotSurface2D_.CopyToClipboard();
02564                         }
02565 
02566                         private void mnuCopyDataToClipboard_Click(object sender, System.EventArgs e) 
02567                         {
02568                                 plotSurface2D_.CopyDataToClipboard();
02569                         }
02570 
02571                         private void mnuPrint_Click(object sender, System.EventArgs e) 
02572                         {
02573                                 plotSurface2D_.Print( false );
02574                         }
02575 
02576                         private void mnuPrintPreview_Click(object sender, System.EventArgs e) 
02577                         {
02578                                 plotSurface2D_.Print( true );
02579                         }
02580 
02581                         private void mnuDisplayCoordinates_Click(object sender, System.EventArgs e)
02582                         {
02583                                 plotSurface2D_.ShowCoordinates = !plotSurface2D_.ShowCoordinates;
02584                         }
02585 
02586                         private void rightMenu__Popup(object sender, System.EventArgs e)
02587                         {
02588                                 foreach (IPlotMenuItem item in menuItems_)
02589                                 {
02590                                         item.OnPopup( this );
02591                                 }
02592                         }
02593 
02597                         public System.Windows.Forms.ContextMenu Menu
02598                         {
02599                                 get
02600                                 {
02601                                         return rightMenu_;
02602                                 }
02603                         }
02604 
02605                 }
02606                 #endregion
02607 
02611                 protected override void Dispose( bool disposing )
02612                 {
02613                         if( disposing )
02614                         {
02615                                 if( components != null )
02616                                         components.Dispose();
02617                         }
02618                         base.Dispose( disposing );
02619                 }
02620 
02621                 private System.ComponentModel.IContainer components;
02622         }
02623 
02624 }

Generated on Sat Nov 5 01:04:06 2005 for NPlot by  doxygen 1.4.5