1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207 |
- // 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: Text annotation class.
- //
- using System;
- using System.Windows.Forms;
- using System.ComponentModel;
- using System.Drawing;
- using System.Drawing.Design;
- using System.Drawing.Drawing2D;
- using System.Security;
- using FastReport.DataVisualization.Charting.Utilities;
- namespace FastReport.DataVisualization.Charting
- {
- using Point = System.Drawing.Point;
- using Size = System.Drawing.Size;
- /// <summary>
- /// <b>TextAnnotation</b> is a class that represents a text annotation.
- /// </summary>
- /// <remarks>
- /// Note that other annotations do display inner text (e.g. rectangle,
- /// ellipse annotations.).
- /// </remarks>
- [
- SRDescription("DescriptionAttributeTextAnnotation_TextAnnotation"),
- ]
- public class TextAnnotation : Annotation
- {
- // Annotation text
- private string _text = "";
- // Indicates multiline text
- private bool _isMultiline = false;
- // Current content size
- internal SizeF contentSize = SizeF.Empty;
- // Indicates that annotion is an ellipse
- internal bool isEllipse = false;
- // Control used to edit text
- private TextBox _editTextBox = null;
- #region Construction and Initialization
- /// <summary>
- /// Default public constructor.
- /// </summary>
- public TextAnnotation()
- : base()
- {
- }
- #endregion
- #region Properties
- #region Text Visual Attributes
- /// <summary>
- /// Annotation's text.
- /// </summary>
- [
- SRCategory("CategoryAttributeAppearance"),
- DefaultValue(""),
- SRDescription("DescriptionAttributeText"),
- ]
- virtual public string Text
- {
- get
- {
- return _text;
- }
- set
- {
- _text = value;
- Invalidate();
- // Reset content size to empty
- contentSize = SizeF.Empty;
- }
- }
- /// <summary>
- /// Indicates whether the annotation text is multiline.
- /// </summary>
- [
- SRCategory("CategoryAttributeAppearance"),
- DefaultValue(false),
- SRDescription("DescriptionAttributeMultiline"),
- ]
- virtual public bool IsMultiline
- {
- get
- {
- return _isMultiline;
- }
- set
- {
- _isMultiline = value;
- Invalidate();
- }
- }
- /// <summary>
- /// Gets or sets the font of an annotation's text.
- /// <seealso cref="Annotation.ForeColor"/>
- /// </summary>
- /// <value>
- /// A <see cref="Font"/> object used for an annotation's text.
- /// </value>
- [
- SRCategory("CategoryAttributeAppearance"),
- DefaultValue(typeof(Font), "Microsoft Sans Serif, 8pt"),
- SRDescription("DescriptionAttributeTextFont4"),
- ]
- override public Font Font
- {
- get
- {
- return base.Font;
- }
- set
- {
- base.Font = value;
- // Reset content size to empty
- contentSize = SizeF.Empty;
- }
- }
- #endregion
- #region Non Applicable Annotation Appearance Attributes (set as Non-Browsable)
- /// <summary>
- /// Not applicable to this annotation type.
- /// </summary>
- [
- SRCategory("CategoryAttributeAppearance"),
- Browsable(false),
- DefaultValue(typeof(Color), "Black"),
- TypeConverter(typeof(ColorConverter)),
- #if DESIGNER
- Editor(typeof(ChartColorEditor), typeof(UITypeEditor))
- #endif
- ]
- override public Color LineColor
- {
- get
- {
- return base.LineColor;
- }
- set
- {
- base.LineColor = value;
- }
- }
- /// <summary>
- /// Not applicable to this annotation type.
- /// </summary>
- [
- SRCategory("CategoryAttributeAppearance"),
- Browsable(false),
- DefaultValue(1),
- SRDescription("DescriptionAttributeLineWidth"),
- ]
- override public int LineWidth
- {
- get
- {
- return base.LineWidth;
- }
- set
- {
- base.LineWidth = value;
- }
- }
- /// <summary>
- /// Not applicable to this annotation type.
- /// </summary>
- [
- SRCategory("CategoryAttributeAppearance"),
- Browsable(false),
- DefaultValue(ChartDashStyle.Solid),
- ]
- override public ChartDashStyle LineDashStyle
- {
- get
- {
- return base.LineDashStyle;
- }
- set
- {
- base.LineDashStyle = value;
- }
- }
- /// <summary>
- /// Not applicable to this annotation type.
- /// </summary>
- [
- SRCategory("CategoryAttributeAppearance"),
- Browsable(false),
- DefaultValue(typeof(Color), ""),
- NotifyParentPropertyAttribute(true),
- TypeConverter(typeof(ColorConverter)),
- #if DESIGNER
- Editor(typeof(ChartColorEditor), typeof(UITypeEditor))
- #endif
- ]
- override public Color BackColor
- {
- get
- {
- return base.BackColor;
- }
- set
- {
- base.BackColor = value;
- }
- }
- /// <summary>
- /// Not applicable to this annotation type.
- /// </summary>
- [
- SRCategory("CategoryAttributeAppearance"),
- Browsable(false),
- DefaultValue(ChartHatchStyle.None),
- NotifyParentPropertyAttribute(true),
- #if DESIGNER
- Editor(typeof(HatchStyleEditor), typeof(UITypeEditor))
- #endif
- ]
- override public ChartHatchStyle BackHatchStyle
- {
- get
- {
- return base.BackHatchStyle;
- }
- set
- {
- base.BackHatchStyle = value;
- }
- }
- /// <summary>
- /// Not applicable to this annotation type.
- /// </summary>
- [
- SRCategory("CategoryAttributeAppearance"),
- Browsable(false),
- DefaultValue(GradientStyle.None),
- NotifyParentPropertyAttribute(true),
- #if DESIGNER
- Editor(typeof(GradientEditor), typeof(UITypeEditor))
- #endif
- ]
- override public GradientStyle BackGradientStyle
- {
- get
- {
- return base.BackGradientStyle;
- }
- set
- {
- base.BackGradientStyle = value;
- }
- }
- /// <summary>
- /// Not applicable to this annotation type.
- /// </summary>
- [
- SRCategory("CategoryAttributeAppearance"),
- Browsable(false),
- DefaultValue(typeof(Color), ""),
- NotifyParentPropertyAttribute(true),
- TypeConverter(typeof(ColorConverter)),
- #if DESIGNER
- Editor(typeof(ChartColorEditor), typeof(UITypeEditor))
- #endif
- ]
- override public Color BackSecondaryColor
- {
- get
- {
- return base.BackSecondaryColor;
- }
- set
- {
- base.BackSecondaryColor = value;
- }
- }
- #endregion
- #region Other
- /// <summary>
- /// Gets or sets an annotation's type name.
- /// </summary>
- /// <remarks>
- /// This property is used to get the name of each annotation type
- /// (e.g. Line, Rectangle, Ellipse).
- /// <para>
- /// This property is for internal use and is hidden at design and run time.
- /// </para>
- /// </remarks>
- [
- SRCategory("CategoryAttributeMisc"),
- Bindable(true),
- Browsable(false),
- EditorBrowsableAttribute(EditorBrowsableState.Never),
- DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden),
- SerializationVisibilityAttribute(SerializationVisibility.Hidden),
- SRDescription("DescriptionAttributeTextAnnotation_AnnotationType"),
- ]
- public override string AnnotationType
- {
- get
- {
- return "Text";
- }
- }
- /// <summary>
- /// Annotation selection points style.
- /// </summary>
- [
- SRCategory("CategoryAttributeAppearance"),
- DefaultValue(SelectionPointsStyle.Rectangle),
- ParenthesizePropertyNameAttribute(true),
- Browsable(false),
- EditorBrowsableAttribute(EditorBrowsableState.Never),
- DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden),
- SerializationVisibilityAttribute(SerializationVisibility.Hidden),
- SRDescription("DescriptionAttributeSelectionPointsStyle"),
- ]
- override internal SelectionPointsStyle SelectionPointsStyle
- {
- get
- {
- return SelectionPointsStyle.Rectangle;
- }
- }
- #endregion
- #endregion
- #region Methods
- #region Painting
- /// <summary>
- /// Paints an annotation object on the specified graphics.
- /// </summary>
- /// <param name="graphics">
- /// A <see cref="ChartGraphics"/> object, used to paint an annotation object.
- /// </param>
- /// <param name="chart">
- /// Reference to the <see cref="Chart"/> owner control.
- /// </param>
- override internal void Paint(Chart chart, ChartGraphics graphics)
- {
- // Get annotation position in relative coordinates
- PointF firstPoint = PointF.Empty;
- PointF anchorPoint = PointF.Empty;
- SizeF size = SizeF.Empty;
- GetRelativePosition(out firstPoint, out size, out anchorPoint);
- PointF secondPoint = new PointF(firstPoint.X + size.Width, firstPoint.Y + size.Height);
- // Create selection rectangle
- RectangleF selectionRect = new RectangleF(firstPoint, new SizeF(secondPoint.X - firstPoint.X, secondPoint.Y - firstPoint.Y));
- // Get text position
- RectangleF textPosition = new RectangleF(selectionRect.Location, selectionRect.Size);
- if(textPosition.Width < 0)
- {
- textPosition.X = textPosition.Right;
- textPosition.Width = -textPosition.Width;
- }
- if(textPosition.Height < 0)
- {
- textPosition.Y = textPosition.Bottom;
- textPosition.Height = -textPosition.Height;
- }
- // Check if text position is valid
- if( textPosition.IsEmpty ||
- float.IsNaN(textPosition.X) ||
- float.IsNaN(textPosition.Y) ||
- float.IsNaN(textPosition.Right) ||
- float.IsNaN(textPosition.Bottom) )
- {
- return;
- }
- if(this.Common.ProcessModePaint)
- {
- DrawText(graphics, textPosition, false, false);
- }
- if(this.Common.ProcessModeRegions)
- {
- // Add hot region
- if(isEllipse)
- {
- using (GraphicsPath ellipsePath = new GraphicsPath())
- {
- ellipsePath.AddEllipse(textPosition);
- this.Common.HotRegionsList.AddHotRegion(
- graphics,
- ellipsePath,
- true,
- ReplaceKeywords(this.ToolTip),
- String.Empty,
- String.Empty,
- String.Empty,
- this,
- ChartElementType.Annotation);
- }
- }
- else
- {
- this.Common.HotRegionsList.AddHotRegion(
- textPosition,
- ReplaceKeywords(this.ToolTip),
- String.Empty,
- String.Empty,
- String.Empty,
- this,
- ChartElementType.Annotation,
- String.Empty);
- }
- }
- // Paint selection handles
- PaintSelectionHandles(graphics, selectionRect, null);
- }
- /// <summary>
- /// Draws text in specified rectangle.
- /// </summary>
- /// <param name="graphics">Chart graphics.</param>
- /// <param name="textPosition">Text position.</param>
- /// <param name="noSpacingForCenteredText">True if text allowed to be outside of position when centered.</param>
- /// <param name="getTextPosition">True if position text must be returned by the method.</param>
- /// <returns>Text actual position if required.</returns>
- internal RectangleF DrawText(ChartGraphics graphics, RectangleF textPosition, bool noSpacingForCenteredText, bool getTextPosition)
- {
- RectangleF textActualPosition = RectangleF.Empty;
- //***************************************************************
- //** Adjust text position uing text spacing
- //***************************************************************
- bool annotationRelative = false;
- RectangleF textSpacing = GetTextSpacing(out annotationRelative);
- float spacingScaleX = 1f;
- float spacingScaleY = 1f;
- if(annotationRelative)
- {
- if(textPosition.Width > 25f)
- {
- spacingScaleX = textPosition.Width / 50f;
- spacingScaleX = Math.Max(1f, spacingScaleX);
- }
- if(textPosition.Height > 25f)
- {
- spacingScaleY = textPosition.Height / 50f;
- spacingScaleY = Math.Max(1f, spacingScaleY);
- }
- }
- RectangleF textPositionWithSpacing = new RectangleF(textPosition.Location, textPosition.Size);
- textPositionWithSpacing.Width -= (textSpacing.Width + textSpacing.X) * spacingScaleX;
- textPositionWithSpacing.X += textSpacing.X * spacingScaleX;
- textPositionWithSpacing.Height -= (textSpacing.Height + textSpacing.Y) * spacingScaleY;
- textPositionWithSpacing.Y += textSpacing.Y * spacingScaleY;
- //***************************************************************
- //** Replace new line characters
- //***************************************************************
- string titleText = this.ReplaceKeywords(this.Text.Replace("\\n", "\n"));
- //***************************************************************
- //** Check if centered text require spacing.
- //** Use only half of the spacing required.
- //** Apply only for 1 line of text.
- //***************************************************************
- if(noSpacingForCenteredText &&
- titleText.IndexOf('\n') == -1)
- {
- if(this.Alignment == ContentAlignment.MiddleCenter ||
- this.Alignment == ContentAlignment.MiddleLeft ||
- this.Alignment == ContentAlignment.MiddleRight)
- {
- textPositionWithSpacing.Y = textPosition.Y;
- textPositionWithSpacing.Height = textPosition.Height;
- textPositionWithSpacing.Height -= textSpacing.Height/2f + textSpacing.Y / 2f;
- textPositionWithSpacing.Y += textSpacing.Y / 2f;
- }
- if(this.Alignment == ContentAlignment.BottomCenter ||
- this.Alignment == ContentAlignment.MiddleCenter ||
- this.Alignment == ContentAlignment.TopCenter)
- {
- textPositionWithSpacing.X = textPosition.X;
- textPositionWithSpacing.Width = textPosition.Width;
- textPositionWithSpacing.Width -= textSpacing.Width/2f + textSpacing.X / 2f;
- textPositionWithSpacing.X += textSpacing.X / 2f;
- }
- }
- // Draw text
- using( Brush textBrush = new SolidBrush(this.ForeColor) )
- {
- using (StringFormat format = new StringFormat(StringFormat.GenericTypographic))
- {
- //***************************************************************
- //** Set text format
- //***************************************************************
- format.FormatFlags = format.FormatFlags ^ StringFormatFlags.LineLimit;
- format.Trimming = StringTrimming.EllipsisCharacter;
- if (this.Alignment == ContentAlignment.BottomRight ||
- this.Alignment == ContentAlignment.MiddleRight ||
- this.Alignment == ContentAlignment.TopRight)
- {
- format.Alignment = StringAlignment.Far;
- }
- if (this.Alignment == ContentAlignment.BottomCenter ||
- this.Alignment == ContentAlignment.MiddleCenter ||
- this.Alignment == ContentAlignment.TopCenter)
- {
- format.Alignment = StringAlignment.Center;
- }
- if (this.Alignment == ContentAlignment.BottomCenter ||
- this.Alignment == ContentAlignment.BottomLeft ||
- this.Alignment == ContentAlignment.BottomRight)
- {
- format.LineAlignment = StringAlignment.Far;
- }
- if (this.Alignment == ContentAlignment.MiddleCenter ||
- this.Alignment == ContentAlignment.MiddleLeft ||
- this.Alignment == ContentAlignment.MiddleRight)
- {
- format.LineAlignment = StringAlignment.Center;
- }
- //***************************************************************
- //** Set shadow color and offset
- //***************************************************************
- Color textShadowColor = ChartGraphics.GetGradientColor(this.ForeColor, Color.Black, 0.8);
- int textShadowOffset = 1;
- TextStyle textStyle = this.TextStyle;
- if (textStyle == TextStyle.Shadow &&
- ShadowOffset != 0)
- {
- // Draw shadowed text
- textShadowColor = ShadowColor;
- textShadowOffset = ShadowOffset;
- }
- if (textStyle == TextStyle.Shadow)
- {
- textShadowColor = (textShadowColor.A != 255) ? textShadowColor : Color.FromArgb(textShadowColor.A / 2, textShadowColor);
- }
- //***************************************************************
- //** Get text actual position
- //***************************************************************
- if (getTextPosition)
- {
- // Measure text size
- SizeF textSize = graphics.MeasureStringRel(
- this.ReplaceKeywords(_text.Replace("\\n", "\n")),
- this.Font,
- textPositionWithSpacing.Size,
- format);
- // Get text position
- textActualPosition = new RectangleF(textPositionWithSpacing.Location, textSize);
- if (this.Alignment == ContentAlignment.BottomRight ||
- this.Alignment == ContentAlignment.MiddleRight ||
- this.Alignment == ContentAlignment.TopRight)
- {
- textActualPosition.X += textPositionWithSpacing.Width - textSize.Width;
- }
- if (this.Alignment == ContentAlignment.BottomCenter ||
- this.Alignment == ContentAlignment.MiddleCenter ||
- this.Alignment == ContentAlignment.TopCenter)
- {
- textActualPosition.X += (textPositionWithSpacing.Width - textSize.Width) / 2f;
- }
- if (this.Alignment == ContentAlignment.BottomCenter ||
- this.Alignment == ContentAlignment.BottomLeft ||
- this.Alignment == ContentAlignment.BottomRight)
- {
- textActualPosition.Y += textPositionWithSpacing.Height - textSize.Height;
- }
- if (this.Alignment == ContentAlignment.MiddleCenter ||
- this.Alignment == ContentAlignment.MiddleLeft ||
- this.Alignment == ContentAlignment.MiddleRight)
- {
- textActualPosition.Y += (textPositionWithSpacing.Height - textSize.Height) / 2f;
- }
- // Do not allow text to go outside annotation position
- textActualPosition.Intersect(textPositionWithSpacing);
- }
- RectangleF absPosition = graphics.GetAbsoluteRectangle(textPositionWithSpacing);
- Title.DrawStringWithStyle(
- graphics,
- titleText,
- this.TextStyle,
- this.Font,
- absPosition,
- this.ForeColor,
- textShadowColor,
- textShadowOffset,
- format,
- TextOrientation.Auto
- );
- }
- }
- return textActualPosition;
- }
- #endregion // Painting
- #region Text Editing
- /// <summary>
- /// Stops editing of the annotation text.
- /// <seealso cref="BeginTextEditing"/>
- /// </summary>
- /// <remarks>
- /// Call this method to cancel text editing, which was started via a call to
- /// the <see cref="BeginTextEditing"/> method, or after the end-user double-clicks
- /// on the annotation.
- /// </remarks>
- public void StopTextEditing()
- {
- // Check if text is currently edited
- if(_editTextBox != null)
- {
- // Set annotation text
- this.Text = _editTextBox.Text;
- // Remove and dispose the text box
- try
- {
- _editTextBox.KeyDown -= new KeyEventHandler(OnTextBoxKeyDown);
- _editTextBox.LostFocus -= new EventHandler(OnTextBoxLostFocus);
- }
- catch(SecurityException)
- {
- // Ignore security issues
- }
-
- if(this.Chart.Controls.Contains(_editTextBox))
- {
- TextBox tempControl = null;
- try
- {
- // NOTE: Workaround .Net bug. Issue with appplication closing if
- // active control is removed.
- Form parentForm = this.Chart.FindForm();
- if(parentForm != null)
- {
- tempControl = new TextBox();
- tempControl.Visible = false;
-
- // Add temp. control as active
- parentForm.Controls.Add(tempControl);
- parentForm.ActiveControl = tempControl;
- }
- }
- catch(SecurityException)
- {
- // Ignore security issues
- }
- // Remove text editor
- this.Chart.Controls.Remove(_editTextBox);
- // Dispose temp. text box
- if(tempControl != null)
- {
- tempControl.Dispose();
- }
- }
- // Dispose edit box
- _editTextBox.Dispose();
- _editTextBox = null;
- // Raise notification event
- if(this.Chart != null)
- {
- this.Chart.OnAnnotationTextChanged(this);
- }
- // Update chart
- if(this.Chart != null)
- {
- this.Chart.Invalidate();
- this.Chart.Update();
- }
- }
- }
- /// <summary>
- /// Handles event when focus is lost by the text editing control.
- /// </summary>
- /// <param name="sender">Event sender.</param>
- /// <param name="e">Event arguments.</param>
- private void OnTextBoxLostFocus(object sender, EventArgs e)
- {
- StopTextEditing();
- }
- /// <summary>
- /// Handles event when key is pressed in the text editing control.
- /// </summary>
- /// <param name="sender">Event sender.</param>
- /// <param name="e">Event arguments.</param>
- private void OnTextBoxKeyDown(object sender, KeyEventArgs e)
- {
- if(e.KeyCode == Keys.Escape)
- {
- // Reset text and stop editing
- _editTextBox.Text = this.Text;
- StopTextEditing();
- }
- else if(e.KeyCode == Keys.Enter &&
- this.IsMultiline == false)
- {
- // Stop editing
- StopTextEditing();
- }
- }
- /// <summary>
- /// Begins editing the annotation's text by an end user.
- /// <seealso cref="StopTextEditing"/>
- /// </summary>
- /// <remarks>
- /// After calling this method, the annotation displays an editing box which allows
- /// for editing of the annotation's text.
- /// <para>
- /// Call the <see cref="StopTextEditing"/> method to cancel this mode programatically.
- /// Note that editing ends when the end-user hits the <c>Enter</c> key if multi-line
- /// is false, or when the end-user clicks outside of the editing box if multi-line is true.
- /// </para>
- /// </remarks>
- public void BeginTextEditing()
- {
- if(this.Chart != null && this.AllowTextEditing)
- {
- // Dispose previous text box
- if(_editTextBox != null)
- {
- if(this.Chart.Controls.Contains(_editTextBox))
- {
- this.Chart.Controls.Remove(_editTextBox);
- }
- _editTextBox.Dispose();
- _editTextBox = null;
- }
- // Create a text box inside the chart
- _editTextBox = new TextBox();
- _editTextBox.Text = this.Text;
- _editTextBox.Multiline = this.IsMultiline;
- _editTextBox.Font = this.Font;
- _editTextBox.BorderStyle = BorderStyle.FixedSingle;
- _editTextBox.BackColor = Color.FromArgb(255, (this.BackColor.IsEmpty) ? Color.White : this.BackColor);
- _editTextBox.ForeColor = Color.FromArgb(255, this.ForeColor);
- // Calculate text position in relative coordinates
- PointF firstPoint = PointF.Empty;
- PointF anchorPoint = PointF.Empty;
- SizeF size = SizeF.Empty;
- GetRelativePosition(out firstPoint, out size, out anchorPoint);
- PointF secondPoint = new PointF(firstPoint.X + size.Width, firstPoint.Y + size.Height);
- RectangleF textPosition = new RectangleF(firstPoint, new SizeF(secondPoint.X - firstPoint.X, secondPoint.Y - firstPoint.Y));
- if(textPosition.Width < 0)
- {
- textPosition.X = textPosition.Right;
- textPosition.Width = -textPosition.Width;
- }
- if(textPosition.Height < 0)
- {
- textPosition.Y = textPosition.Bottom;
- textPosition.Height = -textPosition.Height;
- }
- // Set text control position in pixels
- if(GetGraphics() != null)
- {
- // Convert point to relative coordinates
- textPosition = GetGraphics().GetAbsoluteRectangle(textPosition);
- }
- // Adjust Location and Size
- if(this.IsMultiline)
- {
- textPosition.X -= 1;
- textPosition.Y -= 1;
- textPosition.Width += 2;
- textPosition.Height += 2;
- }
- else
- {
- textPosition.Y += textPosition.Height / 2f - _editTextBox.Size.Height / 2f;
- }
- _editTextBox.Location = Point.Round(textPosition.Location);
- _editTextBox.Size = Size.Round(textPosition.Size);
- // Add control to the chart
- this.Chart.Controls.Add(_editTextBox);
- try
- {
- _editTextBox.SelectAll();
- _editTextBox.Focus();
- }
- catch(SecurityException)
- {
- // Ignore security issues
- }
- try
- {
- // Set text box event hanlers
- _editTextBox.KeyDown += new KeyEventHandler(OnTextBoxKeyDown);
- _editTextBox.LostFocus += new EventHandler(OnTextBoxLostFocus);
- }
- catch(SecurityException)
- {
- // Ignore security issues
- }
- }
- }
- #endregion // Text Editing
- #region Content Size
- /// <summary>
- /// Gets text annotation content size based on the text and font.
- /// </summary>
- /// <returns>Annotation content position.</returns>
- override internal RectangleF GetContentPosition()
- {
- // Return pre calculated value
- if(!contentSize.IsEmpty)
- {
- return new RectangleF(float.NaN, float.NaN, contentSize.Width, contentSize.Height);
- }
- // Create temporary bitmap based chart graphics if chart was not
- // rendered yet and the graphics was not created.
- // NOTE: Fix for issue #3978.
- IGraphics graphics = null;
- System.Drawing.Image graphicsImage = null;
- ChartGraphics tempChartGraph = null;
- if(GetGraphics() == null && this.Common != null)
- {
- graphicsImage = new System.Drawing.Bitmap(Common.ChartPicture.Width, Common.ChartPicture.Height);
- graphics = new FastReport.GdiGraphics( graphicsImage );
- tempChartGraph = new ChartGraphics( Common );
- tempChartGraph.Graphics = graphics;
- tempChartGraph.SetPictureSize( Common.ChartPicture.Width, Common.ChartPicture.Height );
- this.Common.graph = tempChartGraph;
- }
- // Calculate content size
- RectangleF result = RectangleF.Empty;
- if(GetGraphics() != null && this.Text.Trim().Length > 0)
- {
- // Measure text using current font and slightly increase it
- contentSize = GetGraphics().MeasureString(
- "W" + this.ReplaceKeywords(this.Text.Replace("\\n", "\n")),
- this.Font,
- new SizeF(2000, 2000),
- StringFormat.GenericTypographic);
- contentSize.Height *= 1.04f;
- // Convert to relative coordinates
- contentSize = GetGraphics().GetRelativeSize(contentSize);
- // Add spacing
- bool annotationRelative = false;
- RectangleF textSpacing = GetTextSpacing(out annotationRelative);
- float spacingScaleX = 1f;
- float spacingScaleY = 1f;
- if(annotationRelative)
- {
- if(contentSize.Width > 25f)
- {
- spacingScaleX = contentSize.Width / 25f;
- spacingScaleX = Math.Max(1f, spacingScaleX);
- }
- if(contentSize.Height > 25f)
- {
- spacingScaleY = contentSize.Height / 25f;
- spacingScaleY = Math.Max(1f, spacingScaleY);
- }
- }
- contentSize.Width += (textSpacing.X + textSpacing.Width) * spacingScaleX;
- contentSize.Height += (textSpacing.Y + textSpacing.Height) * spacingScaleY;
- result = new RectangleF(float.NaN, float.NaN, contentSize.Width, contentSize.Height);
- }
- // Dispose temporary chart graphics
- if(tempChartGraph != null)
- {
- tempChartGraph.Dispose();
- graphics.Dispose();
- graphicsImage.Dispose();
- this.Common.graph = null;
- }
- return result;
- }
- /// <summary>
- /// Gets text spacing on four different sides in relative coordinates.
- /// </summary>
- /// <param name="annotationRelative">Indicates that spacing is in annotation relative coordinates.</param>
- /// <returns>Rectangle with text spacing values.</returns>
- internal virtual RectangleF GetTextSpacing(out bool annotationRelative)
- {
- annotationRelative = false;
- RectangleF rect = new RectangleF(3f, 3f, 3f, 3f);
- if(GetGraphics() != null)
- {
- rect = GetGraphics().GetRelativeRectangle(rect);
- }
- return rect;
- }
- #endregion
- #region Placement Methods
- /// <summary>
- /// Ends user placement of an annotation.
- /// </summary>
- /// <remarks>
- /// Ends an annotation placement operation previously started by a
- /// <see cref="Annotation.BeginPlacement"/> method call.
- /// <para>
- /// Calling this method is not required, since placement will automatically
- /// end when an end user enters all required points. However, it is useful when an annotation
- /// placement operation needs to be aborted for some reason.
- /// </para>
- /// </remarks>
- override public void EndPlacement()
- {
- // Check if text editing is allowed
- // Maybe changed later in the EndPlacement method.
- bool allowTextEditing = this.AllowTextEditing;
- // Call base class
- base.EndPlacement();
- // Begin text editing
- if(this.Chart != null)
- {
- this.Chart.Annotations.lastClickedAnnotation = this;
- if(allowTextEditing)
- {
- BeginTextEditing();
- }
- }
- }
- #endregion // Placement Methods
- #endregion // Methods
- }
- /// <summary>
- /// The <b>AnnotationSmartLabelStyle</b> class is used to store an annotation's smart
- /// labels properties.
- /// <seealso cref="Annotation.SmartLabelStyle"/>
- /// </summary>
- /// <remarks>
- /// This class is derived from the <b>SmartLabelStyle</b> class
- /// used for <b>Series</b> objects.
- /// </remarks>
- [
- DefaultProperty("Enabled"),
- SRDescription("DescriptionAttributeAnnotationSmartLabelsStyle_AnnotationSmartLabelsStyle"),
- TypeConverter(typeof(NoNameExpandableObjectConverter)),
- ]
- public class AnnotationSmartLabelStyle : SmartLabelStyle
- {
- #region Constructors and initialization
- /// <summary>
- /// Default public constructor.
- /// </summary>
- public AnnotationSmartLabelStyle()
- {
- this.chartElement = null;
- }
- /// <summary>
- /// Constructor.
- /// </summary>
- /// <param name="chartElement">
- /// Chart element this style belongs to.
- /// </param>
- public AnnotationSmartLabelStyle(Object chartElement) : base(chartElement)
- {
- }
- #endregion
- #region Non Applicable Appearance Attributes (set as Non-Browsable)
- /// <summary>
- /// Callout style of the repositioned smart labels.
- /// </summary>
- /// <remarks>
- /// This method is for internal use and is hidden at design time and runtime.
- /// </remarks>
- [
- SRCategory("CategoryAttributeMisc"),
- Browsable(false),
- EditorBrowsableAttribute(EditorBrowsableState.Never),
- DefaultValue(LabelCalloutStyle.Underlined),
- SRDescription("DescriptionAttributeCalloutStyle3"),
- ]
- override public LabelCalloutStyle CalloutStyle
- {
- get
- {
- return base.CalloutStyle;
- }
- set
- {
- base.CalloutStyle = value;
- }
- }
- /// <summary>
- /// Label callout line color.
- /// </summary>
- /// <remarks>
- /// This method is for internal use and is hidden at design and run time.
- /// </remarks>
- [
- SRCategory("CategoryAttributeAppearance"),
- Browsable(false),
- EditorBrowsableAttribute(EditorBrowsableState.Never),
- DefaultValue(typeof(Color), "Black"),
- SRDescription("DescriptionAttributeCalloutLineColor"),
- TypeConverter(typeof(ColorConverter)),
- #if DESIGNER
- Editor(typeof(ChartColorEditor), typeof(UITypeEditor))
- #endif
- ]
- override public Color CalloutLineColor
- {
- get
- {
- return base.CalloutLineColor;
- }
- set
- {
- base.CalloutLineColor = value;
- }
- }
- /// <summary>
- /// Label callout line style.
- /// </summary>
- /// <remarks>
- /// This method is for internal use and is hidden at design and run time.
- /// </remarks>
- [
- SRCategory("CategoryAttributeAppearance"),
- Browsable(false),
- EditorBrowsableAttribute(EditorBrowsableState.Never),
- DefaultValue(ChartDashStyle.Solid),
- SRDescription("DescriptionAttributeLineDashStyle"),
- ]
- override public ChartDashStyle CalloutLineDashStyle
- {
- get
- {
- return base.CalloutLineDashStyle;
- }
- set
- {
- base.CalloutLineDashStyle = value;
- }
- }
- /// <summary>
- /// Label callout back color. Applies to the Box style only.
- /// </summary>
- /// <remarks>
- /// This method is for internal use and is hidden at design and run time.
- /// </remarks>
- [
- SRCategory("CategoryAttributeAppearance"),
- Browsable(false),
- EditorBrowsableAttribute(EditorBrowsableState.Never),
- DefaultValue(typeof(Color), "Transparent"),
- SRDescription("DescriptionAttributeCalloutBackColor"),
- TypeConverter(typeof(ColorConverter)),
- #if DESIGNER
- Editor(typeof(ChartColorEditor), typeof(UITypeEditor))
- #endif
- ]
- override public Color CalloutBackColor
- {
- get
- {
- return base.CalloutBackColor;
- }
- set
- {
- base.CalloutBackColor = value;
- }
- }
- /// <summary>
- /// Label callout line width.
- /// </summary>
- /// <remarks>
- /// This method is for internal use and is hidden at design and run time.
- /// </remarks>
- [
- SRCategory("CategoryAttributeAppearance"),
- Browsable(false),
- EditorBrowsableAttribute(EditorBrowsableState.Never),
- DefaultValue(1),
- SRDescription("DescriptionAttributeLineWidth"),
- ]
- override public int CalloutLineWidth
- {
- get
- {
- return base.CalloutLineWidth;
- }
- set
- {
- base.CalloutLineWidth = value;
- }
- }
- /// <summary>
- /// Label callout line anchor cap.
- /// </summary>
- /// <remarks>
- /// This method is for internal use and is hidden at design and run time.
- /// </remarks>
- [
- SRCategory("CategoryAttributeAppearance"),
- Browsable(false),
- EditorBrowsableAttribute(EditorBrowsableState.Never),
- DefaultValue(LineAnchorCapStyle.Arrow),
- SRDescription("DescriptionAttributeCalloutLineAnchorCapStyle"),
- ]
- override public LineAnchorCapStyle CalloutLineAnchorCapStyle
- {
- get
- {
- return base.CalloutLineAnchorCapStyle;
- }
- set
- {
- base.CalloutLineAnchorCapStyle = value;
- }
- }
- #endregion
- }
- }
|