1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936 |
- // Licensed to the .NET Foundation under one or more agreements.
- // The .NET Foundation licenses this file to you under the MIT license.
- // See the LICENSE file in the project root for more information.
- //
- // Purpose: AxisScrollBar class represent axis scroolbar. There
- // is a big difference how this UI functionality
- // implemented for Windows Forms and ASP.NET. For
- // Windows Forms a custom drawn scrollbar control is
- // drawn in the chart which reacts to the mouse input and
- // changes current axis data scaleView.
- //
- using System;
- using System.Windows.Forms;
- using System.ComponentModel;
- using System.Diagnostics.CodeAnalysis;
- using System.Drawing;
- using System.Drawing.Design;
- using System.Drawing.Drawing2D;
- using FastReport.DataVisualization.Charting.Utilities;
- namespace FastReport.DataVisualization.Charting
- {
- #region Scroll bar enumerations
- /// <summary>
- /// An enumeration of scrollbar button types.
- /// </summary>
- public enum ScrollBarButtonType
- {
- /// <summary>
- /// Thumb tracker button.
- /// </summary>
- ThumbTracker,
- /// <summary>
- /// Scroll by substracting small distance.
- /// </summary>
- SmallDecrement,
- /// <summary>
- /// Scroll by adding small distance.
- /// </summary>
- SmallIncrement,
- /// <summary>
- /// Scroll by substracting large distance.
- /// </summary>
- LargeDecrement,
- /// <summary>
- /// Scroll by adding large distance.
- /// </summary>
- LargeIncrement,
- /// <summary>
- /// Zoom reset button.
- /// </summary>
- ZoomReset
- }
- /// <summary>
- /// An enumeration of scrollbar button style flags.
- /// </summary>
- [Flags]
- public enum ScrollBarButtonStyles
- {
- /// <summary>
- /// No buttons are shown.
- /// </summary>
- None = 0,
- /// <summary>
- /// Small increment or decrement buttons are shown.
- /// </summary>
- SmallScroll = 1,
- /// <summary>
- /// Reset zoom buttons are shown.
- /// </summary>
- ResetZoom = 2,
- /// <summary>
- /// All buttons are shown.
- /// </summary>
- All = SmallScroll | ResetZoom
- }
- #endregion
- /// <summary>
- /// AxisScrollBar class represents the axis scrollbar. It is exposed as the
- /// ScrollBar property of the Axis class. It contains scrollbar appearance
- /// properties and drawing methods.
- /// </summary>
- public class AxisScrollBar : IDisposable
- {
- #region Scroll bar fields
- // Reference to the axis data scaleView class
- internal Axis axis = null;
- // Indicates that scollbra will be drawn
- private bool _enabled = true;
- // Axis data scaleView scroll bar style
- private ScrollBarButtonStyles _scrollBarButtonStyle = ScrollBarButtonStyles.All;
- // Axis data scaleView scroll bar size
- private double _scrollBarSize = 14.0;
- // Index of the pressed butoon in the scroll bar
- private int _pressedButtonType = int.MaxValue;
- // Axis data scaleView scroll bar buttons color
- private Color _buttonColor = Color.Empty;
- // Axis data scaleView scroll bar back color
- private Color _backColor = Color.Empty;
- // Axis data scaleView scroll bar lines color
- private Color _lineColor = Color.Empty;
- // Current scroll bar drawing colors
- private Color _buttonCurrentColor = Color.Empty;
- private Color _backCurrentColor = Color.Empty;
- private Color _lineCurrentColor = Color.Empty;
- // Last mouse click mouse and scaleView position
- private PointF _lastClickMousePosition = PointF.Empty;
- private double _lastClickViewPosition = double.NaN;
- // Timer used to scroll the data while selecting
- private System.Windows.Forms.Timer _scrollTimer = new System.Windows.Forms.Timer();
- // Scroll size and direction when AutoScroll is set
- private MouseEventArgs _mouseArguments = null;
- // Position of the scrollbar (true - edge of PlotArea, false - edge of chart area)
- private bool _isPositionedInside = true;
- #endregion
- #region Scroll bar constructors and initialization
- /// <summary>
- /// AxisScrollBar constructor.
- /// </summary>
- public AxisScrollBar()
- {
- }
- /// <summary>
- /// Axis scroll bar constructor.
- /// </summary>
- /// <param name="axis">Reference to the axis class.</param>
- internal AxisScrollBar(Axis axis)
- {
- // Save reference to the axis data scaleView
- this.axis = axis;
- }
- /// <summary>
- /// Initialize axis scroll bar class.
- /// </summary>
- internal void Initialize()
- {
- }
- #endregion
- #region Scroll bar properties
-
- /// <summary>
- /// Gets or sets a flag which indicates whether scroll bar is positioned inside or outside of chart area.
- /// </summary>
- [
- SRCategory("CategoryAttributeAxisView"),
- Bindable(true),
- DefaultValue(true),
- SRDescription("DescriptionAttributeAxisScrollBar_PositionInside")
- ]
- public bool IsPositionedInside
- {
- get
- {
- return _isPositionedInside;
- }
- set
- {
- if(_isPositionedInside != value)
- {
- _isPositionedInside = value;
- if(axis != null)
- {
- axis.ChartArea.Invalidate();
- axis.CallOnModifing();
- }
- }
- }
- }
- /// <summary>
- /// Gets or sets a flag which indicates whether the scroll bar is enabled.
- /// </summary>
- [
- SRCategory("CategoryAttributeAxisView"),
- Bindable(true),
- DefaultValue(true),
- SRDescription("DescriptionAttributeAxisScrollBar_Enabled")
- ]
- public bool Enabled
- {
- get
- {
- return _enabled;
- }
- set
- {
- if(_enabled != value)
- {
- _enabled = value;
- if(axis != null)
- {
- axis.ChartArea.Invalidate();
- axis.CallOnModifing();
- }
- }
- }
- }
- /// <summary>
- /// Gets the ChartArea that contains this scrollbar.
- /// </summary>
- [
- Browsable(false),
- Bindable(false),
- DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden),
- SerializationVisibilityAttribute(SerializationVisibility.Hidden)
- ]
- public ChartArea ChartArea
- {
- get
- {
- return this.axis.ChartArea;
- }
- }
- /// <summary>
- /// Gets the Axis that contains this scrollbar.
- /// </summary>
- [
- Browsable(false),
- Bindable(false),
- DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden),
- SerializationVisibilityAttribute(SerializationVisibility.Hidden)
- ]
- public Axis Axis
- {
- get
- {
- return this.axis;
- }
- }
- /// <summary>
- /// Gets or sets the style of the scrollbar button.
- /// </summary>
- [
- SRCategory("CategoryAttributeAxisView"),
- Bindable(true),
- DefaultValue(ScrollBarButtonStyles.All),
- SRDescription("DescriptionAttributeAxisScrollBar_Buttons"),
- #if DESIGNER
- Editor(typeof(FlagsEnumUITypeEditor), typeof(UITypeEditor))
- #endif
- ]
- public ScrollBarButtonStyles ButtonStyle
- {
- get
- {
- return _scrollBarButtonStyle;
- }
- set
- {
- if(_scrollBarButtonStyle != value)
- {
- _scrollBarButtonStyle = value;
- if(axis != null)
- {
- axis.ChartArea.Invalidate();
- axis.CallOnModifing();
- }
- }
- }
- }
- /// <summary>
- /// Gets or sets the size of the scrollbar.
- /// </summary>
- [
- SRCategory("CategoryAttributeAxisView"),
- Bindable(true),
- DefaultValue(14.0),
- SRDescription("DescriptionAttributeAxisScrollBar_Size"),
- ]
- public double Size
- {
- get
- {
- return _scrollBarSize;
- }
- set
- {
- if(_scrollBarSize != value)
- {
- // Check values range
- if(value < 5.0 || value > 20.0)
- {
- throw (new ArgumentOutOfRangeException("value", SR.ExceptionScrollBarSizeInvalid));
- }
- _scrollBarSize = value;
- if(axis != null)
- {
- axis.ChartArea.Invalidate();
- axis.CallOnModifing();
- }
- }
- }
- }
- /// <summary>
- /// Gets or sets the button color of the scrollbar.
- /// </summary>
- [
- SRCategory("CategoryAttributeAxisView"),
- Bindable(true),
- DefaultValue(typeof(Color), ""),
- SRDescription("DescriptionAttributeAxisScrollBar_ButtonColor"),
- TypeConverter(typeof(ColorConverter)),
- #if DESIGNER
- Editor(typeof(ChartColorEditor), typeof(UITypeEditor))
- #endif
- ]
- public Color ButtonColor
- {
- get
- {
- return _buttonColor;
- }
- set
- {
- if(_buttonColor != value)
- {
- _buttonColor = value;
- if(axis != null)
- {
- axis.ChartArea.Invalidate();
- axis.CallOnModifing();
- }
- }
- }
- }
- /// <summary>
- /// Gets or sets the line color of the scrollbar.
- /// </summary>
- [
- SRCategory("CategoryAttributeAxisView"),
- Bindable(true),
- DefaultValue(typeof(Color), ""),
- SRDescription("DescriptionAttributeLineColor"),
- TypeConverter(typeof(ColorConverter)),
- #if DESIGNER
- Editor(typeof(ChartColorEditor), typeof(UITypeEditor))
- #endif
- ]
- public Color LineColor
- {
- get
- {
- return _lineColor;
- }
- set
- {
- if(_lineColor != value)
- {
- _lineColor = value;
- if(axis != null)
- {
- axis.ChartArea.Invalidate();
- axis.CallOnModifing();
- }
- }
- }
- }
- /// <summary>
- /// Gets or sets the background color of the scrollbar.
- /// </summary>
- [
- SRCategory("CategoryAttributeAxisView"),
- Bindable(true),
- DefaultValue(typeof(Color), ""),
- SRDescription("DescriptionAttributeBackColor"),
- TypeConverter(typeof(ColorConverter)),
- #if DESIGNER
- Editor(typeof(ChartColorEditor), typeof(UITypeEditor))
- #endif
- ]
- public Color BackColor
- {
- get
- {
- return _backColor;
- }
- set
- {
- if(_backColor != value)
- {
- _backColor = value;
- if(axis != null)
- {
- axis.ChartArea.Invalidate();
- axis.CallOnModifing();
- }
- }
- }
- }
- #endregion
- #region Scroll bar public methods
- /// <summary>
- /// This method returns true if the scrollbar is visible.
- /// </summary>
- [Browsable(false)]
- [Utilities.SerializationVisibility(Utilities.SerializationVisibility.Hidden)]
- public bool IsVisible
- {
- get
- {
- // Check scroll bar enabled flag
- if (!this.Enabled)
- {
- return false;
- }
- // Do not show scroll bars while printing
- if (this.axis == null ||
- this.axis.ChartArea == null ||
- this.axis.ChartArea.Common == null ||
- this.axis.ChartArea.Common.ChartPicture == null ||
- this.axis.ChartArea.Common.ChartPicture.isPrinting)
- {
- return false;
- }
- #if SUBAXES
- // Scrollbar is not supported on the sub axis
- if(this.axis.IsSubAxis)
- {
- return false;
- }
- #endif // SUBAXES
- // Check if data scaleView size in percentage is less than 100%
- return (GetDataViewPercentage() < 100.0) ? true : false;
- }
- }
- #endregion
- #region Scroll bar painting methods
- /// <summary>
- /// Draws axis scroll bar.
- /// </summary>
- /// <param name="graph">Reference to the Chart Graphics object.</param>
- internal void Paint( ChartGraphics graph )
- {
- // Scroll bar border width
- int borderWidth = 1;
- // Scroll bar should not be visible
- if(!this.IsVisible)
- {
- return;
- }
- #if SUBAXES
- // Scrollbar not supported on sub axis
- if( this.axis != null && this.axis.IsSubAxis)
- {
- return;
- }
- #endif //SUBAXES
- // Set current scroll bar colors
- _buttonCurrentColor = this._buttonColor;
- _backCurrentColor = this._backColor;
- _lineCurrentColor = this._lineColor;
- // Make sure the current colors are not empty
- if(_buttonCurrentColor == Color.Empty)
- {
- _buttonCurrentColor = this.axis.ChartArea.BackColor;
- if(_buttonCurrentColor == Color.Empty)
- {
- _buttonCurrentColor = Color.DarkGray;
- }
- }
- if(_backCurrentColor == Color.Empty)
- {
- _backCurrentColor = this.axis.ChartArea.BackColor;
- if(_backCurrentColor == Color.Empty)
- {
- _backCurrentColor = Color.LightGray;
- }
- }
- if(_lineCurrentColor == Color.Empty)
- {
- _lineCurrentColor = this.axis.LineColor;
- if(_lineCurrentColor == Color.Empty)
- {
- _lineCurrentColor = Color.Black;
- }
- }
- // Get scroll bar rectangle
- RectangleF scrollBarRect = this.GetScrollBarRect();
- // Fill scroll bar background
- graph.FillRectangleRel(
- scrollBarRect,
- _backCurrentColor,
- ChartHatchStyle.None,
- "",
- ChartImageWrapMode.Tile,
- Color.Empty,
- ChartImageAlignmentStyle.Center,
- GradientStyle.None,
- Color.Empty,
- _lineCurrentColor,
- borderWidth,
- ChartDashStyle.Solid,
- Color.Empty,
- 0,
- PenAlignment.Outset );
- // Fill rectangle between to neighbour scroll bars
- PaintScrollBarConnectionRect(graph, scrollBarRect, borderWidth);
- // Get scroll bar client rectangle
- SizeF borderRelativeSize = new SizeF(borderWidth, borderWidth);
- borderRelativeSize = graph.GetRelativeSize(borderRelativeSize);
- RectangleF scrollBarClientRect = new RectangleF(scrollBarRect.Location, scrollBarRect.Size);
- scrollBarClientRect.Inflate(-borderRelativeSize.Width, -borderRelativeSize.Height);
- // Draw all button types
- foreach (ScrollBarButtonType buttonType in Enum.GetValues(typeof(ScrollBarButtonType)))
- {
- // Get button rectangle
- RectangleF buttonRect = this.GetScrollBarButtonRect(scrollBarClientRect, (ScrollBarButtonType)buttonType);
- // Paint button
- if(!buttonRect.IsEmpty)
- {
- PaintScrollBar3DButton(
- graph,
- buttonRect,
- ((ScrollBarButtonType)this._pressedButtonType) == (ScrollBarButtonType)buttonType,
- (ScrollBarButtonType)buttonType);
- }
- }
- if( this.ChartArea.Common.ProcessModeRegions )
- {
- SetHotRegionElement( this.ChartArea.Common );
- }
- }
-
- /// <summary>
- /// Fills a connection rectangle between two scoll bars.
- /// </summary>
- /// <param name="graph">Chart graphics.</param>
- /// <param name="scrollBarRect">Scroll bar position.</param>
- /// <param name="borderWidth">Border width.</param>
- private void PaintScrollBarConnectionRect(
- ChartGraphics graph,
- RectangleF scrollBarRect,
- int borderWidth)
- {
- // Do not draw anything if scroll bar is vertical
- if(this.axis.AxisPosition == AxisPosition.Left ||
- this.axis.AxisPosition == AxisPosition.Right)
- {
- return;
- }
- // Check if scoll bar is shown on the left/right sides of
- // the plotting area and get their sizes in relative coordinates
- float leftSize = 0f;
- float rightSize = 0f;
- foreach(Axis a in this.axis.ChartArea.Axes)
- {
- if(a.AxisPosition == AxisPosition.Left && a.ScrollBar.IsVisible && a.ScrollBar.IsPositionedInside == this.axis.ScrollBar.IsPositionedInside)
- {
- leftSize = (float)a.ScrollBar.GetScrollBarRelativeSize();
- }
- if(a.AxisPosition == AxisPosition.Right && a.ScrollBar.IsVisible && a.ScrollBar.IsPositionedInside == this.axis.ScrollBar.IsPositionedInside)
- {
- rightSize = (float)a.ScrollBar.GetScrollBarRelativeSize();
- }
- }
- // Prepare generic rectangle coordinates
- RectangleF connectorRect = new RectangleF(scrollBarRect.Location, scrollBarRect.Size);
- // Prepare coordinates and fill area to the left
- if(leftSize > 0f)
- {
- connectorRect.X = scrollBarRect.X - leftSize;
- connectorRect.Width = leftSize;
- // Fill background
- graph.FillRectangleRel(
- connectorRect,
- _backCurrentColor,
- ChartHatchStyle.None,
- "",
- ChartImageWrapMode.Tile,
- Color.Empty,
- ChartImageAlignmentStyle.Center,
- GradientStyle.None,
- Color.Empty,
- _lineCurrentColor,
- borderWidth,
- ChartDashStyle.Solid,
- Color.Empty,
- 0,
- PenAlignment.Outset );
- }
- // Prepare coordinates and fill area to the right
- if(rightSize > 0f)
- {
- connectorRect.X = scrollBarRect.Right;
- connectorRect.Width = rightSize;
- // Fill background
- graph.FillRectangleRel(
- connectorRect,
- _backCurrentColor,
- ChartHatchStyle.None,
- "",
- ChartImageWrapMode.Tile,
- Color.Empty,
- ChartImageAlignmentStyle.Center,
- GradientStyle.None,
- Color.Empty,
- _lineCurrentColor,
- borderWidth,
- ChartDashStyle.Solid,
- Color.Empty,
- 0,
- PenAlignment.Outset );
- }
- }
- /// <summary>
- /// Draws 3D button in the scroll bar
- /// </summary>
- /// <param name="graph">Chart graphics.</param>
- /// <param name="buttonRect">Button position.</param>
- /// <param name="pressedState">Indicates that button is pressed.</param>
- /// <param name="buttonType">Button type to draw.</param>
- internal void PaintScrollBar3DButton(
- ChartGraphics graph,
- RectangleF buttonRect,
- bool pressedState,
- ScrollBarButtonType buttonType)
- {
- // Page Up/Down buttons do not require drawing
- if(buttonType == ScrollBarButtonType.LargeIncrement || buttonType == ScrollBarButtonType.LargeDecrement)
- {
- return;
- }
- // Get 3 levels of colors for button drawing
- Color darkerColor = ChartGraphics.GetGradientColor(_buttonCurrentColor, Color.Black, 0.5);
- Color darkestColor = ChartGraphics.GetGradientColor(_buttonCurrentColor, Color.Black, 0.8);
- Color lighterColor = ChartGraphics.GetGradientColor(_buttonCurrentColor, Color.White, 0.5);
- // Fill button rectangle background
- graph.FillRectangleRel(
- buttonRect,
- _buttonCurrentColor,
- ChartHatchStyle.None,
- "",
- ChartImageWrapMode.Tile,
- Color.Empty,
- ChartImageAlignmentStyle.Center,
- GradientStyle.None,
- Color.Empty,
- darkerColor,
- (pressedState) ? 1 : 0,
- ChartDashStyle.Solid,
- Color.Empty,
- 0,
- PenAlignment.Outset );
- // Check if 2 or 1 pixel border will be drawn (if size too small)
- bool singlePixelBorder = this.Size <= 12;
- // Draw 3D effect around the button when not pressed
- if(!pressedState)
- {
- // Get relative size of 1 pixel
- SizeF pixelRelativeSize = new SizeF(1, 1);
- pixelRelativeSize = graph.GetRelativeSize(pixelRelativeSize);
- // Draw top/left border with button color
- graph.DrawLineRel(
- (singlePixelBorder) ? lighterColor : _buttonCurrentColor, 1, ChartDashStyle.Solid,
- new PointF(buttonRect.X, buttonRect.Bottom),
- new PointF(buttonRect.X, buttonRect.Top));
- graph.DrawLineRel(
- (singlePixelBorder) ? lighterColor : _buttonCurrentColor, 1, ChartDashStyle.Solid,
- new PointF(buttonRect.Left, buttonRect.Y),
- new PointF(buttonRect.Right, buttonRect.Y));
- // Draw right/bottom border with the darkest color
- graph.DrawLineRel(
- (singlePixelBorder) ? darkerColor : darkestColor, 1, ChartDashStyle.Solid,
- new PointF(buttonRect.Right, buttonRect.Bottom),
- new PointF(buttonRect.Right, buttonRect.Top));
- graph.DrawLineRel(
- (singlePixelBorder) ? darkerColor : darkestColor, 1, ChartDashStyle.Solid,
- new PointF(buttonRect.Left, buttonRect.Bottom),
- new PointF(buttonRect.Right, buttonRect.Bottom));
- if(!singlePixelBorder)
- {
- // Draw right/bottom border (offset 1) with the dark color
- graph.DrawLineRel(
- darkerColor, 1, ChartDashStyle.Solid,
- new PointF(buttonRect.Right-pixelRelativeSize.Width, buttonRect.Bottom-pixelRelativeSize.Height),
- new PointF(buttonRect.Right-pixelRelativeSize.Width, buttonRect.Top+pixelRelativeSize.Height));
- graph.DrawLineRel(
- darkerColor, 1, ChartDashStyle.Solid,
- new PointF(buttonRect.Left+pixelRelativeSize.Width, buttonRect.Bottom-pixelRelativeSize.Height),
- new PointF(buttonRect.Right-pixelRelativeSize.Width, buttonRect.Bottom-pixelRelativeSize.Height));
- // Draw top/left border (offset 1) with lighter color
- graph.DrawLineRel(
- lighterColor, 1, ChartDashStyle.Solid,
- new PointF(buttonRect.X+pixelRelativeSize.Width, buttonRect.Bottom-pixelRelativeSize.Height),
- new PointF(buttonRect.X+pixelRelativeSize.Width, buttonRect.Top+pixelRelativeSize.Height));
- graph.DrawLineRel(
- lighterColor, 1, ChartDashStyle.Solid,
- new PointF(buttonRect.Left+pixelRelativeSize.Width, buttonRect.Y+pixelRelativeSize.Height),
- new PointF(buttonRect.Right-pixelRelativeSize.Width, buttonRect.Y+pixelRelativeSize.Height));
- }
- }
- // Check axis orientation
- bool verticalAxis = (this.axis.AxisPosition == AxisPosition.Left ||
- this.axis.AxisPosition == AxisPosition.Right) ? true : false;
- // Set graphics transformation for button pressed mode
- float pressedShifting = (singlePixelBorder) ? 0.5f : 1f;
- if(pressedState)
- {
- graph.TranslateTransform(pressedShifting, pressedShifting);
- }
- // Draw button image
- RectangleF buttonAbsRect = graph.GetAbsoluteRectangle(buttonRect);
- float imageOffset = (singlePixelBorder) ? 2 : 3;
- switch(buttonType)
- {
- case(ScrollBarButtonType.SmallDecrement):
- {
- // Calculate triangal points position
- PointF[] points = new PointF[3];
- if(verticalAxis)
- {
- points[0].X = buttonAbsRect.X + imageOffset;
- points[0].Y = buttonAbsRect.Y + (imageOffset + 1f);
- points[1].X = buttonAbsRect.X + buttonAbsRect.Width/2f;
- points[1].Y = buttonAbsRect.Bottom - imageOffset;
- points[2].X = buttonAbsRect.Right - imageOffset;
- points[2].Y = buttonAbsRect.Y + (imageOffset + 1f);
- }
- else
- {
- points[0].X = buttonAbsRect.X + imageOffset;
- points[0].Y = buttonAbsRect.Y + buttonAbsRect.Height/2f;
- points[1].X = buttonAbsRect.Right - (imageOffset + 1f);
- points[1].Y = buttonAbsRect.Y + imageOffset;
- points[2].X = buttonAbsRect.Right - (imageOffset + 1f);
- points[2].Y = buttonAbsRect.Bottom - imageOffset;
- }
- using (Brush brush = new SolidBrush(this._lineCurrentColor))
- {
- graph.FillPolygon(brush, points);
- }
- break;
- }
- case(ScrollBarButtonType.SmallIncrement):
- {
- // Calculate triangal points position
- PointF[] points = new PointF[3];
- if(verticalAxis)
- {
- points[0].X = buttonAbsRect.X + imageOffset;
- points[0].Y = buttonAbsRect.Bottom - (imageOffset + 1f);
- points[1].X = buttonAbsRect.X + buttonAbsRect.Width/2f;
- points[1].Y = buttonAbsRect.Y + imageOffset;
- points[2].X = buttonAbsRect.Right - imageOffset;
- points[2].Y = buttonAbsRect.Bottom - (imageOffset + 1f);
- }
- else
- {
- points[0].X = buttonAbsRect.Right - imageOffset;
- points[0].Y = buttonAbsRect.Y + buttonAbsRect.Height/2f;
- points[1].X = buttonAbsRect.X + (imageOffset + 1f);
- points[1].Y = buttonAbsRect.Y + imageOffset;
- points[2].X = buttonAbsRect.X + (imageOffset + 1f);
- points[2].Y = buttonAbsRect.Bottom - imageOffset;
- }
- using (Brush brush = new SolidBrush(this._lineCurrentColor))
- {
- graph.FillPolygon(brush, points);
- }
- break;
- }
- case(ScrollBarButtonType.ZoomReset):
- {
- // Draw circule with a minus sign
- using (Pen pen = new Pen(this._lineCurrentColor, 1))
- {
- graph.DrawEllipse(pen, buttonAbsRect.X + imageOffset - 0.5f, buttonAbsRect.Y + imageOffset - 0.5f, buttonAbsRect.Width - 2f * imageOffset, buttonAbsRect.Height - 2f * imageOffset);
- graph.DrawLine(pen, buttonAbsRect.X + imageOffset + 1.5f, buttonAbsRect.Y + buttonAbsRect.Height / 2f - 0.5f, buttonAbsRect.Right - imageOffset - 2.5f, buttonAbsRect.Y + buttonAbsRect.Height / 2f - 0.5f);
- }
- break;
- }
- }
- // Reset graphics transformation for button pressed mode
- if(pressedState)
- {
- graph.TranslateTransform(-pressedShifting, -pressedShifting);
- }
- }
- #endregion
- #region Mouse events handling for the Scroll Bar
- /// <summary>
- /// Mouse down event handler.
- /// </summary>
- internal void ScrollBar_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
- {
- // Process left mouse button
- if(e.Button == MouseButtons.Left && this.IsVisible)
- {
- // Remember position where mouse was clicked
- _lastClickMousePosition = new PointF(e.X, e.Y);
- _lastClickViewPosition = this.axis.ScaleView.Position;
- // Check if button was pressed inside the scroll bar
- ScrollBarButtonType buttonType;
- if(GetElementByPixelPosition(e.X, e.Y, out buttonType))
- {
- this.ButtonClicked(buttonType, e.X, e.Y);
- }
- }
- }
- /// <summary>
- /// Mouse up event handler.
- /// </summary>
- internal void ScrollBar_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
- {
- // If scroll bar button was pressed
- if(this._pressedButtonType != int.MaxValue)
- {
- // Check if button was unpressed inside the reset zoom button
- ScrollBarButtonType buttonType;
- if(GetElementByPixelPosition(e.X, e.Y, out buttonType))
- {
- if(buttonType == ScrollBarButtonType.ZoomReset)
- {
- this.ButtonClicked(buttonType, e.X, e.Y);
- }
- }
- // Stop scrolling timer
- _scrollTimer.Stop();
- _mouseArguments = null;
- // Clear pressed button state
- this._pressedButtonType = int.MaxValue;
- // Invalidate chart
- this.axis.Invalidate();
- }
- }
- /// <summary>
- /// Mouse move event handler.
- /// </summary>
- internal void ScrollBar_MouseMove(System.Windows.Forms.MouseEventArgs e, ref bool handled)
- {
- // If scroll bar button was pressed
- if(this._pressedButtonType != int.MaxValue)
- {
- // Mouse move event should not be handled by any other chart elements
- handled = true;
- // Check if tracking buton was pressed
- if((ScrollBarButtonType)this._pressedButtonType == ScrollBarButtonType.ThumbTracker)
- {
- // Proceed if last clicked position is known
- if(!_lastClickMousePosition.IsEmpty)
- {
- this.ButtonClicked(ScrollBarButtonType.ThumbTracker, e.X, e.Y);
- }
- }
- // Non tracking scroll bar button
- else
- {
- // Check if mouse cursor is still in the pressed button's rectangle
- bool inPressedButton = false;
- ScrollBarButtonType buttonType;
- if(GetElementByPixelPosition(e.X, e.Y, out buttonType))
- {
- if(buttonType == (ScrollBarButtonType)this._pressedButtonType)
- {
- inPressedButton = true;
- }
- }
- // Clear pressed button state
- if(!inPressedButton)
- {
- // Stop scrolling timer
- _scrollTimer.Stop();
- _mouseArguments = null;
- // Clear pressed button state
- this._pressedButtonType = int.MaxValue;
- // Invalidate chart
- this.axis.Invalidate();
- }
- }
- }
- }
- /// <summary>
- /// Scroll bar button was clicked by the user.
- /// </summary>
- /// <param name="buttonType">Button type.</param>
- /// <param name="x">X click position in pixels.</param>
- /// <param name="y">Y click position in pixels.</param>
- [SuppressMessage("Microsoft.Mobility", "CA1601:DoNotUseTimersThatPreventPowerStateChanges", Justification = "The timer is used for simulating scrolling behavior")]
- private void ButtonClicked(ScrollBarButtonType buttonType, int x, int y)
- {
- // Call zoom reset on the second pass when button is released
- if(buttonType != ScrollBarButtonType.ZoomReset ||
- (ScrollBarButtonType)this._pressedButtonType == buttonType)
- {
- //**************************************************
- //** Fire scroll bar button clicked event
- //**************************************************
- ScrollBarEventArgs eventArg = new ScrollBarEventArgs(this.axis, x, y, buttonType);
- this.axis.ScaleView.GetChartObject().OnAxisScrollBarClicked(eventArg);
- // Check if event was handled by user
- if(eventArg.IsHandled)
- {
- // Save type of the button pressed
- this._pressedButtonType = (int)buttonType;
- return;
- }
- //**************************************************
- //** Scroll data scaleView
- //**************************************************
- switch(buttonType)
- {
- case(ScrollBarButtonType.SmallIncrement):
- this.axis.ScaleView.Scroll(ScrollType.SmallIncrement, true);
- break;
- case(ScrollBarButtonType.SmallDecrement):
- this.axis.ScaleView.Scroll(ScrollType.SmallDecrement, true);
- break;
- case(ScrollBarButtonType.LargeIncrement):
- this.axis.ScaleView.Scroll(ScrollType.LargeIncrement, true);
- break;
- case(ScrollBarButtonType.LargeDecrement):
- this.axis.ScaleView.Scroll(ScrollType.LargeDecrement, true);
- break;
- case(ScrollBarButtonType.ZoomReset):
- this.axis.ScaleView.ZoomReset(1, true);
- break;
- case(ScrollBarButtonType.ThumbTracker):
- {
- if(!_lastClickMousePosition.IsEmpty &&
- !double.IsNaN(this._lastClickViewPosition) &&
- (_lastClickMousePosition.X != x || _lastClickMousePosition.Y != y))
- {
- // Get scroll bar client rectangle
- RectangleF scrollBarRect = this.GetScrollBarRect();
- SizeF borderRelativeSize = new SizeF(1, 1);
- borderRelativeSize = this.GetRelativeSize(borderRelativeSize);
- RectangleF scrollBarClientRect = new RectangleF(scrollBarRect.Location, scrollBarRect.Size);
- scrollBarClientRect.Inflate(-borderRelativeSize.Width, -borderRelativeSize.Height);
- // Check axis orientation
- bool verticalAxis = (this.axis.AxisPosition == AxisPosition.Left ||
- this.axis.AxisPosition == AxisPosition.Right) ? true : false;
- // Get button relative size
- SizeF buttonSize = new SizeF(scrollBarClientRect.Width, scrollBarClientRect.Height);
- buttonSize = this.GetAbsoluteSize(buttonSize);
- if(verticalAxis)
- {
- buttonSize.Height = buttonSize.Width;
- }
- else
- {
- buttonSize.Width = buttonSize.Height;
- }
- buttonSize = this.GetRelativeSize(buttonSize);
- // Calculate the distance in percentages the mouse was moved
- // from it's original (clicked) position.
- float distance = 0f;
- double trackingAreaSize = 0f;
- if(verticalAxis)
- {
- // Calculate max tracking size
- trackingAreaSize = scrollBarClientRect.Height - this.GetButtonsNumberAll() * buttonSize.Height;
- distance = _lastClickMousePosition.Y - y;
- // Convert to relative coordinates
- distance = distance * 100F / ((float)(this.axis.Common.Height - 1));
- }
- else
- {
- trackingAreaSize = scrollBarClientRect.Width - this.GetButtonsNumberAll() * buttonSize.Width;
- distance = x - _lastClickMousePosition.X;
- // Convert to relative coordinates
- distance = distance * 100F / ((float)(this.axis.Common.Width - 1));
- }
- // Convert to percentages from total tracking area
- distance = (float)(distance / (trackingAreaSize / 100f));
- // Get axis scale size without margins
- double axisScaleSize = Math.Abs(
- (this.axis.maximum - this.axis.marginView) -
- (this.axis.minimum + this.axis.marginView));
- // Calculate the same percentage using axis scale
- distance = (float)(distance * (axisScaleSize/100f));
- // Round the distance to the minimum scroll line size
- if(!double.IsNaN(axis.ScaleView.SmallScrollMinSize) && axis.ScaleView.SmallScrollMinSize != 0.0)
- {
- double minSize = ChartHelper.GetIntervalSize(0, axis.ScaleView.SmallScrollMinSize, axis.ScaleView.SmallScrollMinSizeType);
- double rounder = (Math.Round(distance / minSize));
- distance = (float)(rounder * minSize);
- }
- // Scroll scaleView into the new position
- this.axis.ScaleView.Scroll(this._lastClickViewPosition + ((this.axis.IsReversed) ? -1 : 1) * distance, true);
- }
- break;
- }
- }
- //************************************************************
- //** Initialize timer for repeating scroll (if mouse is hold)
- //************************************************************
- // Reset mouse arguments
- _mouseArguments = null;
- if(buttonType != ScrollBarButtonType.ThumbTracker && buttonType != ScrollBarButtonType.ZoomReset)
- {
- // Remember last mouse position
- _mouseArguments = new MouseEventArgs(MouseButtons.Left, 1, x, y, 0);
- // Enable timer
- if(!_scrollTimer.Enabled)
- {
- _scrollTimer.Tick += new EventHandler(ScrollingTimerEventProcessor);
- _scrollTimer.Interval = 400;
- _scrollTimer.Start();
- }
- }
- }
- //************************************************************
- //** Invalidate chart
- //************************************************************
-
- // Save type of the button pressed
- this._pressedButtonType = (int)buttonType;
- // Invalidate
- this.axis.Invalidate();
- }
- /// <summary>
- /// This is the method to run when the timer is raised.
- /// Used to repetedly scroll data scaleView while mouse button is pressed.
- /// </summary>
- /// <param name="myObject">Object.</param>
- /// <param name="myEventArgs">Event arguments.</param>
- [SuppressMessage("Microsoft.Mobility", "CA1601:DoNotUseTimersThatPreventPowerStateChanges", Justification = "The timer is used for simulating scrolling behavior")]
- private void ScrollingTimerEventProcessor(Object myObject, EventArgs myEventArgs)
- {
- // Simulate mouse move events
- if(_mouseArguments != null)
- {
- _scrollTimer.Interval = 200;
- this.ScrollBar_MouseDown(null, _mouseArguments);
- }
- }
- /// <summary>
- /// This method fills hot region collection with scroll bar elements.
- /// Possible elements are all scroll bar buttons and scroll bar background
- /// which performs PgUp/PgDn action.
- /// </summary>
- /// <param name="common">Common Elements</param>
- private void SetHotRegionElement( CommonElements common )
- {
- // Check if mouse button was clicked in the scroll bar
- RectangleF scrollBarRect = this.GetScrollBarRect();
- // Get scroll bar client rectangle
- SizeF borderRelativeSize = new SizeF(1, 1);
- borderRelativeSize = this.GetRelativeSize(borderRelativeSize);
- RectangleF scrollBarClientRect = new RectangleF(scrollBarRect.Location, scrollBarRect.Size);
- scrollBarClientRect.Inflate(-borderRelativeSize.Width, -borderRelativeSize.Height);
-
- ChartElementType buttonType = ChartElementType.Nothing;
- // Fill collection with scroll buttons rectangles.
- foreach(object type in Enum.GetValues(typeof(ScrollBarButtonType)))
- {
- // Convert Scroll Bar Button type enum to Chart Element AxisName enum.
- switch( (ScrollBarButtonType)type )
- {
- case ScrollBarButtonType.SmallIncrement:
- buttonType = ChartElementType.ScrollBarSmallIncrement;
- break;
- case ScrollBarButtonType.LargeIncrement:
- buttonType = ChartElementType.ScrollBarLargeIncrement;
- break;
- case ScrollBarButtonType.LargeDecrement:
- buttonType = ChartElementType.ScrollBarLargeDecrement;
- break;
- case ScrollBarButtonType.ThumbTracker:
- buttonType = ChartElementType.ScrollBarThumbTracker;
- break;
- case ScrollBarButtonType.SmallDecrement:
- buttonType = ChartElementType.ScrollBarSmallDecrement;
- break;
- case ScrollBarButtonType.ZoomReset:
- buttonType = ChartElementType.ScrollBarZoomReset;
- break;
- }
- // Get button rectangle
- RectangleF buttonRect = this.GetScrollBarButtonRect(scrollBarClientRect, (ScrollBarButtonType)type);
- common.HotRegionsList.AddHotRegion( buttonRect, this, buttonType, true );
-
- }
- }
- /// <summary>
- /// Detects the scroll bar elements by pixel position.
- /// Possible elements are all scroll bar buttons and scroll bar background
- /// which performs PgUp/PgDn action.
- /// </summary>
- /// <param name="x">X coordinate in pixels.</param>
- /// <param name="y">Y coordinate in pixels.</param>
- /// <param name="buttonType">Return button type.</param>
- /// <returns>True if position is in the scroll bar.</returns>
- private bool GetElementByPixelPosition(float x, float y, out ScrollBarButtonType buttonType)
- {
- // Set initial values
- buttonType = ScrollBarButtonType.ThumbTracker;
- // Convert mouse click coordinates to relative
- PointF position = new PointF(x, y);
- position.X = x * 100F / ((float)(this.axis.Common.Width - 1));
- position.Y = y * 100F / ((float)(this.axis.Common.Height - 1));
- // Check if mouse button was clicked in the scroll bar
- RectangleF scrollBarRect = this.GetScrollBarRect();
- if(scrollBarRect.Contains(position))
- {
- // Get scroll bar client rectangle
- SizeF borderRelativeSize = new SizeF(1, 1);
- borderRelativeSize = this.GetRelativeSize(borderRelativeSize);
- RectangleF scrollBarClientRect = new RectangleF(scrollBarRect.Location, scrollBarRect.Size);
- scrollBarClientRect.Inflate(-borderRelativeSize.Width, -borderRelativeSize.Height);
- //******************************************************************
- //** Check if scroll bar button was clicked
- //******************************************************************
- foreach(object type in Enum.GetValues(typeof(ScrollBarButtonType)))
- {
- // Get button rectangle
- RectangleF buttonRect = this.GetScrollBarButtonRect(scrollBarClientRect, (ScrollBarButtonType)type);
- // Check if position is inside the button
- if(buttonRect.Contains(position))
- {
- buttonType = (ScrollBarButtonType)type;
- return true;
- }
- }
- }
- // Pixel position is outside scroll bar area
- return false;
- }
- #endregion
- #region Scroll bar helper methods
- /// <summary>
- /// Returns scroll bar button rectangle position in relative coordinates.
- /// </summary>
- /// <param name="scrollBarClientRect">Scroll bar client rectangle.</param>
- /// <param name="buttonType">Scroll bar button type.</param>
- /// <returns>Scroll bar position.</returns>
- internal RectangleF GetScrollBarButtonRect(RectangleF scrollBarClientRect, ScrollBarButtonType buttonType)
- {
- // Initialize button rectangle
- RectangleF buttonRect = new RectangleF(scrollBarClientRect.Location, scrollBarClientRect.Size);
- // Check axis orientation
- bool verticalAxis = (this.axis.AxisPosition == AxisPosition.Left ||
- this.axis.AxisPosition == AxisPosition.Right) ? true : false;
- // Get relative size of 1 pixel
- SizeF pixelRelativeSize = new SizeF(1, 1);
- pixelRelativeSize = this.GetRelativeSize(pixelRelativeSize);
- // Get button relative size
- SizeF buttonSize = new SizeF(scrollBarClientRect.Width, scrollBarClientRect.Height);
- buttonSize = this.GetAbsoluteSize(buttonSize);
- if(verticalAxis)
- {
- buttonSize.Height = buttonSize.Width;
- }
- else
- {
- buttonSize.Width = buttonSize.Height;
- }
- buttonSize = this.GetRelativeSize(buttonSize);
- // Set common position sizes
- buttonRect.Width = buttonSize.Width;
- buttonRect.Height = buttonSize.Height;
- if(verticalAxis)
- {
- buttonRect.X = scrollBarClientRect.X;
- }
- else
- {
- buttonRect.Y = scrollBarClientRect.Y;
- }
- // Calculate scroll bar buttons position
- switch(buttonType)
- {
- case(ScrollBarButtonType.LargeDecrement):
- case(ScrollBarButtonType.LargeIncrement):
- case(ScrollBarButtonType.ThumbTracker):
- {
- // Get tracker button position and size first
- if(verticalAxis)
- {
- // Calculate tracker size
- double trackingAreaSize = scrollBarClientRect.Height - this.GetButtonsNumberAll() * buttonSize.Height;
- buttonRect.Height = (float)(this.GetDataViewPercentage() * (trackingAreaSize / 100f));
- // Check if tracker size is too small
- if(buttonRect.Height < pixelRelativeSize.Height * 6f)
- {
- buttonRect.Height = pixelRelativeSize.Height * 6f;
- }
- // Calculate tracker position
- if(!this.axis.IsReversed)
- {
- buttonRect.Y = scrollBarClientRect.Bottom - this.GetButtonsNumberBottom()*buttonSize.Height - buttonRect.Height;
- buttonRect.Y -= (float)(this.GetDataViewPositionPercentage() * (trackingAreaSize / 100f));
- if(buttonRect.Y < scrollBarClientRect.Y + this.GetButtonsNumberTop()*buttonSize.Height + ((this.GetButtonsNumberTop() == 0) ? 0 : pixelRelativeSize.Height))
- {
- buttonRect.Y = scrollBarClientRect.Y + this.GetButtonsNumberTop()*buttonSize.Height + ((this.GetButtonsNumberTop() == 0) ? 0 : pixelRelativeSize.Height);
- }
- }
- else
- {
- buttonRect.Y = scrollBarClientRect.Top + this.GetButtonsNumberTop()*buttonSize.Height;
- buttonRect.Y += (float)(this.GetDataViewPositionPercentage() * (trackingAreaSize / 100f));
- if((buttonRect.Y + buttonRect.Height) > scrollBarClientRect.Bottom - this.GetButtonsNumberBottom()*buttonSize.Height - ((this.GetButtonsNumberBottom() == 0) ? 0 : pixelRelativeSize.Height))
- {
- buttonRect.Y = (scrollBarClientRect.Bottom - this.GetButtonsNumberBottom()*buttonSize.Height) - buttonRect.Height - ((this.GetButtonsNumberBottom() == 0) ? 0 : pixelRelativeSize.Height);
- }
- }
- }
- else
- {
- // Calculate tracker size
- double trackingAreaSize = scrollBarClientRect.Width - this.GetButtonsNumberAll() * buttonSize.Width;
- buttonRect.Width = (float)(this.GetDataViewPercentage() * (trackingAreaSize / 100f));
- // Check if tracker size is too small
- if(buttonRect.Width < pixelRelativeSize.Width * 6f)
- {
- buttonRect.Width = pixelRelativeSize.Width * 6f;
- }
- // Calculate tracker position
- if(!this.axis.IsReversed)
- {
- buttonRect.X = scrollBarClientRect.X + this.GetButtonsNumberTop() * buttonSize.Width;
- buttonRect.X += (float)(this.GetDataViewPositionPercentage() * (trackingAreaSize / 100f));
- if((buttonRect.X + buttonRect.Width) > scrollBarClientRect.Right - this.GetButtonsNumberBottom()*buttonSize.Width - ((this.GetButtonsNumberBottom() == 0) ? 0 : pixelRelativeSize.Width))
- {
- buttonRect.X = (scrollBarClientRect.Right - buttonRect.Width) - this.GetButtonsNumberBottom()*buttonSize.Width - ((this.GetButtonsNumberBottom() == 0) ? 0 : pixelRelativeSize.Width);
- }
- }
- else
- {
- buttonRect.X = scrollBarClientRect.Right - this.GetButtonsNumberBottom()*buttonSize.Width - ((this.GetButtonsNumberBottom() == 0) ? 0 : pixelRelativeSize.Width) - buttonRect.Width;
- buttonRect.X -= (float)(this.GetDataViewPositionPercentage() * (trackingAreaSize / 100f));
- if(buttonRect.X < scrollBarClientRect.X + this.GetButtonsNumberTop()*buttonSize.Width)
- {
- buttonRect.X = scrollBarClientRect.X + this.GetButtonsNumberTop()*buttonSize.Width;
- }
- }
- }
- // Get page up region rectangle depending on the tracker position
- if(buttonType == ScrollBarButtonType.LargeDecrement)
- {
- if(verticalAxis)
- {
- buttonRect.Y = buttonRect.Bottom + pixelRelativeSize.Height;
- buttonRect.Height = (scrollBarClientRect.Bottom - this.GetButtonsNumberBottom()*buttonSize.Height - pixelRelativeSize.Height) - buttonRect.Y;
- }
- else
- {
- float x = scrollBarClientRect.X +
- this.GetButtonsNumberTop() * buttonSize.Width +
- pixelRelativeSize.Width;
- buttonRect.Width = buttonRect.X - x;
- buttonRect.X = x;
- }
- }
- // Get page down region rectangle depending on the tracker position
- else if(buttonType == ScrollBarButtonType.LargeIncrement)
- {
- if(verticalAxis)
- {
- float y = scrollBarClientRect.Y +
- this.GetButtonsNumberTop() * buttonSize.Height +
- pixelRelativeSize.Height;
- buttonRect.Height = buttonRect.Y - y;
- buttonRect.Y = y;
- }
- else
- {
- buttonRect.X = buttonRect.Right + pixelRelativeSize.Width;
- buttonRect.Width = (scrollBarClientRect.Right - this.GetButtonsNumberBottom()*buttonSize.Width - pixelRelativeSize.Height) - buttonRect.X;
- }
- }
- break;
- }
- case(ScrollBarButtonType.SmallDecrement):
- if(this._scrollBarButtonStyle == ScrollBarButtonStyles.All ||
- this._scrollBarButtonStyle == ScrollBarButtonStyles.SmallScroll)
- {
- if(verticalAxis)
- {
- buttonRect.Y = scrollBarClientRect.Bottom - buttonRect.Height;
- }
- else
- {
- buttonRect.X = scrollBarClientRect.X + (this.GetButtonsNumberTop()-1f)*buttonSize.Width;
- buttonRect.X += (this.GetButtonsNumberTop() == 1) ? 0 : pixelRelativeSize.Width;
- }
- }
- else
- {
- buttonRect = RectangleF.Empty;
- }
- break;
- case(ScrollBarButtonType.SmallIncrement):
- if(this._scrollBarButtonStyle == ScrollBarButtonStyles.All ||
- this._scrollBarButtonStyle == ScrollBarButtonStyles.SmallScroll)
- {
- if(verticalAxis)
- {
- buttonRect.Y = scrollBarClientRect.Y + (this.GetButtonsNumberTop()-1f) * buttonSize.Height;
- buttonRect.Y += (this.GetButtonsNumberTop() == 1) ? 0 : pixelRelativeSize.Height;
- }
- else
- {
- buttonRect.X = scrollBarClientRect.Right - buttonRect.Width;
- }
- }
- else
- {
- buttonRect = RectangleF.Empty;
- }
- break;
- case(ScrollBarButtonType.ZoomReset):
- if(this._scrollBarButtonStyle == ScrollBarButtonStyles.All ||
- this._scrollBarButtonStyle == ScrollBarButtonStyles.ResetZoom)
- {
- if(verticalAxis)
- {
- buttonRect.Y = scrollBarClientRect.Y;
- }
- else
- {
- buttonRect.X = scrollBarClientRect.X;
- }
- }
- else
- {
- buttonRect = RectangleF.Empty;
- }
- break;
- }
- return buttonRect;
- }
- /// <summary>
- /// Returns scroll bar rectangle position in relative coordinates.
- /// </summary>
- /// <returns>Scroll bar position.</returns>
- internal RectangleF GetScrollBarRect()
- {
- // Get scroll bar relative size
- float scrollBarSize = (float)this.GetScrollBarRelativeSize();
- // Get relative size of the axis line (Note: Code removed for now. -- AG)
- //SizeF axisLineSize = new SizeF(axis.LineWidth, axis.LineWidth);
- //axisLineSize.Width = axisLineSize.Width * 100F / ((float)(this.axis.Common.Width - 1));
- //axisLineSize.Height = axisLineSize.Height * 100F / ((float)(this.axis.Common.Height - 1));
- // Check if scroll bar is positioned next to PlotArea or ChartArea
- RectangleF areaPosition = axis.PlotAreaPosition.ToRectangleF();
- if(!this.IsPositionedInside)
- {
- areaPosition = axis.ChartArea.Position.ToRectangleF();
- // Reduce rectangle size by scroll bar size
- foreach(Axis a in this.ChartArea.Axes)
- {
- if(a.ScrollBar.IsVisible && !a.ScrollBar.IsPositionedInside)
- {
- float size = (float)a.ScrollBar.GetScrollBarRelativeSize();
- switch( a.AxisPosition )
- {
- case AxisPosition.Left:
- areaPosition.X += size;
- areaPosition.Width -= size;
- break;
- case AxisPosition.Right:
- areaPosition.Width -= size;
- break;
- case AxisPosition.Bottom:
- areaPosition.Height -= size;
- break;
- case AxisPosition.Top:
- areaPosition.Y += size;
- areaPosition.Height -= size;
- break;
- }
- }
- }
- }
- // Get bar position depending on the axis type
- RectangleF barPosition = RectangleF.Empty;
- if(this.axis.PlotAreaPosition != null)
- {
- switch( axis.AxisPosition )
- {
- case AxisPosition.Left:
- barPosition.Y = areaPosition.Y;
- barPosition.Height = areaPosition.Height;
- barPosition.X =
- ( (this.IsPositionedInside) ? (float)(axis.GetAxisPosition(true)) : areaPosition.X) - scrollBarSize;// - axisLineSize.Width / 2f;
- barPosition.Width = scrollBarSize;
- break;
- case AxisPosition.Right:
- barPosition.Y = areaPosition.Y;
- barPosition.Height = areaPosition.Height;
- barPosition.X =
- (this.IsPositionedInside) ? (float)axis.GetAxisPosition(true) : areaPosition.Right;// + axisLineSize.Width / 2f;
- barPosition.Width = scrollBarSize;
- break;
- case AxisPosition.Bottom:
- barPosition.X = areaPosition.X;
- barPosition.Width = areaPosition.Width;
- barPosition.Y =
- (this.IsPositionedInside) ? (float)axis.GetAxisPosition(true) : areaPosition.Bottom;// + axisLineSize.Height / 2f;
- barPosition.Height = scrollBarSize;
- break;
- case AxisPosition.Top:
- barPosition.X = areaPosition.X;
- barPosition.Width = areaPosition.Width;
- barPosition.Y =
- ( (this.IsPositionedInside) ? (float)axis.GetAxisPosition(true) : areaPosition.Y) - scrollBarSize;// - axisLineSize.Height / 2f;
- barPosition.Height = scrollBarSize;
- break;
- }
- }
-
- return barPosition;
- }
- /// <summary>
- /// Internal helper method which returns the relative scroll bar size.
- /// </summary>
- /// <returns>Relative scroll bar size.</returns>
- internal double GetScrollBarRelativeSize()
- {
- // Scroll bar is not shown in 3D
- if(this.axis.ChartArea.Area3DStyle.Enable3D || this.axis.ChartArea.chartAreaIsCurcular)
- {
- return 0.0;
- }
- #if SUBAXES
- // Scrollbar not supported on sub axis
- if( this.axis != null && this.axis.IsSubAxis)
- {
- return 0.0;
- }
- #endif //SUBAXES
- // Get scroll bar relative size depending on the axis location
- if(this.axis.AxisPosition == AxisPosition.Left || this.axis.AxisPosition == AxisPosition.Right)
- {
- return this._scrollBarSize * 100F / ((float)(this.axis.Common.Width - 1));
- }
- else
- {
- return this._scrollBarSize * 100F / ((float)(this.axis.Common.Height - 1));
- }
- }
- /// <summary>
- /// Returns the percentage size (0-100%) of the data scaleView comparing to
- /// the axis scale minimum and maximum values.
- /// </summary>
- /// <returns>Size of the data scaleView in percentage.</returns>
- private double GetDataViewPercentage()
- {
- double viewPercentage = 100.0;
- // Check if axis data scaleView properties are set
- if(this.axis != null &&
- !double.IsNaN(this.axis.ScaleView.Position) &&
- !double.IsNaN(this.axis.ScaleView.Size))
- {
- // Get data scaleView size
- double dataViewSize = ChartHelper.GetIntervalSize(
- this.axis.ScaleView.Position,
- this.axis.ScaleView.Size,
- this.axis.ScaleView.SizeType);
- // Get axis scale size without margins
- double minimum = this.axis.minimum + this.axis.marginView;
- double maximum = this.axis.maximum - this.axis.marginView;
- if(this.axis.ScaleView.Position < minimum)
- {
- minimum = this.axis.ScaleView.Position;
- }
- if((this.axis.ScaleView.Position + dataViewSize) > maximum)
- {
- maximum = this.axis.ScaleView.Position + dataViewSize;
- }
- double axisScaleSize = Math.Abs(minimum - maximum);
- // Check if data scaleView is smaller than axis scale and if it is find the pecentage
- if(dataViewSize < axisScaleSize)
- {
- viewPercentage = dataViewSize / (axisScaleSize / 100.0);
- }
- }
- return viewPercentage;
- }
- /// <summary>
- /// Returns the the data scaleView position in percentage (0-100%) using
- /// the axis scale minimum and maximum values.
- /// </summary>
- /// <returns>Data scaleView position in percentage.</returns>
- private double GetDataViewPositionPercentage()
- {
- double viewPosition = 0.0;
- // Check if axis data scaleView properties are set
- if(this.axis != null &&
- !double.IsNaN(this.axis.ScaleView.Position) &&
- !double.IsNaN(this.axis.ScaleView.Size))
- {
- // Get data scaleView size
- double dataViewSize = ChartHelper.GetIntervalSize(
- this.axis.ScaleView.Position,
- this.axis.ScaleView.Size,
- this.axis.ScaleView.SizeType);
- // Get axis scale size without margins
- double minimum = this.axis.minimum + this.axis.marginView;
- double maximum = this.axis.maximum - this.axis.marginView;
- if(this.axis.ScaleView.Position < minimum)
- {
- minimum = this.axis.ScaleView.Position;
- }
- if((this.axis.ScaleView.Position + dataViewSize) > maximum)
- {
- maximum = this.axis.ScaleView.Position + dataViewSize;
- }
- double axisScaleSize = Math.Abs(minimum - maximum);
- // Calculate data scaleView position in percentage
- viewPosition = (this.axis.ScaleView.Position - (minimum)) / (axisScaleSize / 100.0);
- }
- return viewPosition;
- }
- /// <summary>
- /// Get total number of buttons in the scroll bar (except tracker).
- /// </summary>
- /// <returns>Number of buttons.</returns>
- private int GetButtonsNumberAll()
- {
- int buttonNumber = 0;
- if((this._scrollBarButtonStyle & ScrollBarButtonStyles.ResetZoom) == ScrollBarButtonStyles.ResetZoom)
- {
- buttonNumber += 1;
- }
- if((this._scrollBarButtonStyle & ScrollBarButtonStyles.SmallScroll) == ScrollBarButtonStyles.SmallScroll)
- {
- buttonNumber += 2;
- }
- return buttonNumber;
- }
- /// <summary>
- /// Get number of buttons in the top (left) part of the scroll bar.
- /// </summary>
- /// <returns>Number of buttons.</returns>
- private int GetButtonsNumberTop()
- {
- int buttonNumber = 0;
- if((this._scrollBarButtonStyle & ScrollBarButtonStyles.ResetZoom) == ScrollBarButtonStyles.ResetZoom)
- {
- buttonNumber += 1;
- }
- if((this._scrollBarButtonStyle & ScrollBarButtonStyles.SmallScroll) == ScrollBarButtonStyles.SmallScroll)
- {
- buttonNumber += 1;
- }
- return buttonNumber;
- }
- /// <summary>
- /// Get number of buttons in the bottom (right) part of the scroll bar.
- /// </summary>
- /// <returns>Number of buttons.</returns>
- private int GetButtonsNumberBottom()
- {
- int buttonNumber = 0;
- if((this._scrollBarButtonStyle & ScrollBarButtonStyles.SmallScroll) == ScrollBarButtonStyles.SmallScroll)
- {
- buttonNumber += 1;
- }
- return buttonNumber;
- }
- #endregion
- #region Coordinate convertion methods
- /// <summary>
- /// Converts Relative size to Absolute size
- /// </summary>
- /// <param name="relative">Relative size in %</param>
- /// <returns>Absolute size</returns>
- internal SizeF GetAbsoluteSize( SizeF relative )
- {
- SizeF absolute = SizeF.Empty;
- // Convert relative coordinates to absolute coordinates
- absolute.Width = relative.Width * (this.axis.Common.Width - 1) / 100F;
- absolute.Height = relative.Height * (this.axis.Common.Height - 1) / 100F;
-
- // Return Absolute coordinates
- return absolute;
- }
- /// <summary>
- /// Converts Absolute size to Relative size
- /// </summary>
- /// <param name="size">Absolute size</param>
- /// <returns>Relative size</returns>
- internal SizeF GetRelativeSize( SizeF size )
- {
- SizeF relative = SizeF.Empty;
- // Convert absolute coordinates to relative coordinates
- relative.Width = size.Width * 100F / ((float)(this.axis.Common.Width - 1));
- relative.Height = size.Height * 100F / ((float)(this.axis.Common.Height - 1));
-
- // Return relative coordinates
- return relative;
- }
- #endregion
- #region IDisposable Members
- /// <summary>
- /// Releases unmanaged and - optionally - managed resources
- /// </summary>
- /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
- protected virtual void Dispose(bool disposing)
- {
- if (disposing)
- {
- // Dispose managed resources
- if (this._scrollTimer != null)
- {
- this._scrollTimer.Dispose();
- this._scrollTimer = null;
- }
- }
- }
- /// <summary>
- /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
- /// </summary>
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
- #endregion
- }
- /// <summary>
- /// The arguments for a scrollbar event.
- /// </summary>
- public class ScrollBarEventArgs : EventArgs
- {
- #region Private fields
- // Private fields for properties values storage
- private Axis _axis = null;
- private bool _isHandled = false;
- private int _mousePositionX = 0;
- private int _mousePositionY = 0;
- private ScrollBarButtonType _buttonType = ScrollBarButtonType.ThumbTracker;
- #endregion
- #region Constructors
- /// <summary>
- /// ScrollBarEventArgs constructor.
- /// </summary>
- /// <param name="axis">Axis containing the scrollbar.</param>
- /// <param name="x">X position of mouse cursor.</param>
- /// <param name="y">Y position of mouse cursor.</param>
- /// <param name="buttonType">Button type of the button clicked.</param>
- [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly",
- Justification = "X and Y are cartesian coordinates and well understood")]
- public ScrollBarEventArgs(Axis axis, int x, int y, ScrollBarButtonType buttonType)
- {
- this._axis = axis;
- this._mousePositionX = x;
- this._mousePositionY = y;
- this._buttonType = buttonType;
- }
- #endregion
- #region Properties
- /// <summary>
- /// Axis containing the scrollbar of the event.
- /// </summary>
- [
- SRDescription("DescriptionAttributeAxis"),
- ]
- public Axis Axis
- {
- get
- {
- return _axis;
- }
- }
- /// <summary>
- /// ChartArea containing the scrollbar of the event.
- /// </summary>
- [
- SRDescription("DescriptionAttributeChartArea"),
- ]
- public ChartArea ChartArea
- {
- get
- {
- return _axis.ChartArea;
- }
- }
- /// <summary>
- /// Button type of the scrollbar button clicked.
- /// </summary>
- [
- SRDescription("DescriptionAttributeScrollBarEventArgs_ButtonType"),
- ]
- public ScrollBarButtonType ButtonType
- {
- get
- {
- return _buttonType;
- }
- }
-
- /// <summary>
- /// Indicates if the event is handled by the user and no further processing is required.
- /// </summary>
- [
- SRDescription("DescriptionAttributeScrollBarEventArgs_Handled"),
- ]
- public bool IsHandled
- {
- get
- {
- return _isHandled;
- }
- set
- {
- _isHandled = value;
- }
- }
- /// <summary>
- /// X position of mouse cursor.
- /// </summary>
- [
- SRDescription("DescriptionAttributeScrollBarEventArgs_MousePositionX"),
- ]
- public int MousePositionX
- {
- get
- {
- return _mousePositionX;
- }
- }
- /// <summary>
- /// Y position of mouse cursor.
- /// </summary>
- [
- SRDescription("DescriptionAttributeScrollBarEventArgs_MousePositionY"),
- ]
- public int MousePositionY
- {
- get
- {
- return _mousePositionY;
- }
- }
- #endregion
- }
- }
|