protected override void OnRender(ChartControl chartControl, ChartScale chartScale) { // Create a Font, Brush and TextFormat to draw our text. // For more information on drawing Text, please see the source code for the Text DrawingTool var font = new Gui.Tools.SimpleFont("Arial", 20); SharpDX.Direct2D1.Brush tmpBrush = Brushes.Red.ToDxBrush(RenderTarget); SharpDX.DirectWrite.TextFormat textFormat = font.ToDirectWriteTextFormat(); // Create a TextLayout for our text to draw. var cachedTextLayout = new SharpDX.DirectWrite.TextLayout(Core.Globals.DirectWriteFactory, "Hello, I am sideways text.", textFormat, 600, textFormat.FontSize); // Rotate the RenderTarget by setting the Matrix3x2 Transform property // Matrix3x2.Rotation() will return a rotated Matrix3x2 based off of the angle specified, and the center point where you draw the object RenderTarget.Transform = Matrix3x2.Rotation(1.5708f, new Vector2(100, 100)); // Draw the text on the rotated RenderTarget RenderTarget.DrawTextLayout(new SharpDX.Vector2(100, 100), cachedTextLayout, tmpBrush, SharpDX.Direct2D1.DrawTextOptions.NoSnap); // Dispose of resources textFormat.Dispose(); cachedTextLayout.Dispose(); tmpBrush.Dispose(); // Rotate the RenderTarget back RenderTarget.Transform = Matrix3x2.Identity; // Return rendering to base class base.OnRender(chartControl, chartScale); }
public override void OnRender(ChartControl chartControl, ChartScale chartScale) { ChartPanel panel = chartControl.ChartPanels[PanelIndex]; UpdateArcGeometry(chartControl, panel, chartScale); base.OnRender(chartControl, chartScale); RenderTarget.AntialiasMode = SharpDX.Direct2D1.AntialiasMode.PerPrimitive; if (AreaBrush != null && !IsInHitTest) { areaBrushDevice.RenderTarget = RenderTarget; if (areaBrushDevice.Brush == null) { Brush brushCopy = AreaBrush.Clone(); brushCopy.Opacity = areaOpacity / 100d; areaBrushDevice.Brush = brushCopy; } RenderTarget.FillGeometry(arcGeometry, areaBrushDevice.BrushDX); } ArcStroke.RenderTarget = RenderTarget; SharpDX.Direct2D1.Brush tmpBrush = IsInHitTest ? chartControl.SelectionBrush : ArcStroke.BrushDX; RenderTarget.DrawGeometry(arcGeometry, tmpBrush, ArcStroke.Width, ArcStroke.StrokeStyle); }
private void drawRow(ChartControl chartControl, ChartScale chartScale, double value, int quantity) { //Calculate color of this row. Brush brushColor = NormalColor; if (value <= MaxId + ValueArea && value >= MaxId - ValueArea) { brushColor = ValueColor; } //Calculate cell properties double y1 = ((chartScale.GetYByValue(value) + chartScale.GetYByValue(value + 1)) / 2) + 1; double y2 = ((chartScale.GetYByValue(value) + chartScale.GetYByValue(value - 1)) / 2) - 1; SharpDX.RectangleF rect = new SharpDX.RectangleF(); rect.X = (float)chartControl.CanvasRight; rect.Y = (float)y1; rect.Width = (float)((chartControl.CanvasLeft - chartControl.CanvasRight) * Math.Log(quantity) / Math.Log(Max)); rect.Height = (float)Math.Abs(y1 - y2); //Draw the row. using (SharpDX.Direct2D1.Brush rowBrush = brushColor.ToDxBrush(RenderTarget)) { RenderTarget.FillRectangle(rect, rowBrush); //RenderTarget.FillRectangle(rect, rowBrush); } if (rect.Height > this.MinimumTextHeight) { RenderTarget.DrawText(string.Format("{0}", quantity), textFormat, rect, TextColor.ToDxBrush(RenderTarget)); } }
private void drawRow(ChartControl chartControl, ChartScale chartScale, RowData row) { //Calculate color of this row. //Brush brushColor = new SolidColorBrush(System.Windows.Media.Color.FromRgb(255, 0, 0)); //bidColor.Freeze(); float alpha = alpha = (float)((double)Math.Abs(row.TotalVolume) / (double)myProfile.HiValue); Brush brushColor = neutralColor; //Calculate width of this row. //Calculate cell properties double y1 = ((chartScale.GetYByValue(row.Price) + chartScale.GetYByValue(row.Price + TickSize)) / 2) + 1; double y2 = ((chartScale.GetYByValue(row.Price) + chartScale.GetYByValue(row.Price - TickSize)) / 2) - 1; SharpDX.RectangleF rect = new SharpDX.RectangleF(); rect.X = (float)chartControl.CanvasRight - Position; rect.Y = (float)y1; rect.Width = (float)-((ResizableWidth * alpha) + MinimumWidth - 2); rect.Height = (float)Math.Abs(y1 - y2); //Draw the row. using (SharpDX.Direct2D1.Brush rowBrush = brushColor.ToDxBrush(RenderTarget)) { //rowBrush.Opacity = alpha; rowBrush.Opacity = alpha; RenderTarget.FillRectangle(rect, neutralColor.ToDxBrush(RenderTarget)); RenderTarget.FillRectangle(rect, rowBrush); } if (rect.Height > this.MinimumTextHeight) { RenderTarget.DrawText(string.Format("{0}", row.TotalVolume), textFormat, rect, TextColor.ToDxBrush(RenderTarget)); } }
public override void OnRender(ChartControl chartControl, ChartScale chartScale) { base.OnRender(chartControl, chartScale); InitializeDrawingTools(); //Calculate where to draw the text. //Refer to parent class Lines.cs OnRender method for more information. ChartPanel panel = chartControl.ChartPanels[chartScale.PanelIndex]; double strokePixAdj = ((double)(Stroke.Width % 2)).ApproxCompare(0) == 0 ? 0.5d : 0d; Vector pixelAdjustVec = new Vector(strokePixAdj, strokePixAdj); Point endPoint = EndAnchor.GetPoint(chartControl, panel, chartScale); Point endPointAdjusted = endPoint + pixelAdjustVec; SharpDX.Vector2 endVec = endPointAdjusted.ToVector2(); //Calculate the current price. string text = (Text != "" ? Text : chartControl.Instrument.MasterInstrument.FormatPrice(chartScale.GetValueByY(endVec.Y), true)); //Set properties for rectangle to draw the object. TextLayout tl = new TextLayout(Core.Globals.DirectWriteFactory, text, cachedTextFormat, ChartPanel.W, ChartPanel.H); SharpDX.RectangleF rect = new SharpDX.RectangleF(); rect.X = (float)endVec.X; rect.Y = (float)endVec.Y - 6f; rect.Width = (float)-(tl.Metrics.Width); rect.Height = (float)-(tl.Metrics.Height); //Draw the text. using (SharpDX.Direct2D1.Brush myDxBrush = TextColor.ToDxBrush(RenderTarget)) { chartScale.GetValueByY(endVec.Y); RenderTarget.DrawText(string.Format("{0}", text), cachedTextFormat, rect, myDxBrush); } }
protected override void OnRenderInitialized(RenderGraphics g) { theme = RenderTheme.CreateResourcesForGraphics(g); bmpTracks[Channel.Square1] = g.CreateBitmapFromResource("Square"); bmpTracks[Channel.Square2] = g.CreateBitmapFromResource("Square"); bmpTracks[Channel.Triangle] = g.CreateBitmapFromResource("Triangle"); bmpTracks[Channel.Noise] = g.CreateBitmapFromResource("Noise"); bmpTracks[Channel.DPCM] = g.CreateBitmapFromResource("DPCM"); bmpGhostNote = g.CreateBitmapFromResource("GhostSmall"); seekBarBrush = g.CreateSolidBrush(ThemeBase.SeekBarColor); whiteKeyBrush = g.CreateHorizontalGradientBrush(0, trackNameSizeX, ThemeBase.LightGreyFillColor1, ThemeBase.LightGreyFillColor2); patternHeaderBrush = g.CreateVerticalGradientBrush(0, patternHeaderSizeY, ThemeBase.LightGreyFillColor1, ThemeBase.LightGreyFillColor2); selectedPatternVisibleBrush = g.CreateSolidBrush(Color.FromArgb(64, ThemeBase.LightGreyFillColor1)); selectedPatternInvisibleBrush = g.CreateSolidBrush(Color.FromArgb(32, ThemeBase.LightGreyFillColor1)); seekGeometry = g.CreateConvexPath(new[] { new Point(-headerSizeY / 2, 1), new Point(0, headerSizeY - 2), new Point(headerSizeY / 2, 1) }); }
public override void OnRender(ChartControl chartControl, ChartScale chartScale) { LineColor.RenderTarget = RenderTarget; // first of all, turn on anti-aliasing to smooth out our line RenderTarget.AntialiasMode = SharpDX.Direct2D1.AntialiasMode.PerPrimitive; ChartPanel panel = chartControl.ChartPanels[chartScale.PanelIndex]; // draw a line from start measure point to end measure point. Point lineStartPoint = StartAnchor.GetPoint(chartControl, panel, chartScale); Point lineEndPoint = EndAnchor.GetPoint(chartControl, panel, chartScale); // align to full pixel to avoid unneeded aliasing double strokePixAdjust = (LineColor.Width % 2).ApproxCompare(0) == 0 ? 0.5d : 0d; Vector strokePixAdjustVec = new Vector(strokePixAdjust, strokePixAdjust); SharpDX.Vector2 endVec = (lineEndPoint + strokePixAdjustVec).ToVector2(); SharpDX.Direct2D1.Brush tmpBrush = IsInHitTest ? chartControl.SelectionBrush : LineColor.BrushDX; RenderTarget.DrawLine((lineStartPoint + strokePixAdjustVec).ToVector2(), endVec, tmpBrush, LineColor.Width, LineColor.StrokeStyle); if (ShouldDrawText) { UpdateTextLayout(chartControl, ChartPanel, chartScale); textDeviceBrush.RenderTarget = RenderTarget; // Text rec uses same settings as mini data box textBackgroundDeviceBrush.Brush = Application.Current.FindResource("ChartControl.DataBoxBackground") as Brush; textBackgroundDeviceBrush.RenderTarget = RenderTarget; Brush borderBrush = Application.Current.FindResource("BorderThinBrush") as Brush; object thicknessResource = Application.Current.FindResource("BorderThinThickness"); double thickness = thicknessResource as double? ?? 1; Stroke textBorderStroke = new Stroke(borderBrush ?? LineColor.Brush, DashStyleHelper.Solid, Convert.ToSingle(thickness)) { RenderTarget = RenderTarget }; Point textEndPoint = TextAnchor.GetPoint(chartControl, panel, chartScale); SharpDX.Vector2 textEndVec = (textEndPoint + strokePixAdjustVec).ToVector2(); RenderTarget.DrawLine(endVec, textEndVec, LineColor.BrushDX, LineColor.Width, LineColor.StrokeStyle); float rectPixAdjust = (float)(strokePixAdjust / 2f); SharpDX.RectangleF rect = new SharpDX.RectangleF((float)(textEndPoint.X - textLayout.MaxWidth - textMargin + rectPixAdjust), (float)(textEndPoint.Y - textLayout.MaxHeight - textMargin + rectPixAdjust), textLayout.MaxWidth + textMargin * 2f, textLayout.MaxHeight + textMargin); if (textBackgroundDeviceBrush.BrushDX != null && !IsInHitTest) { RenderTarget.FillRectangle(rect, textBackgroundDeviceBrush.BrushDX); } RenderTarget.DrawRectangle(rect, textBorderStroke.BrushDX, textBorderStroke.Width, textBorderStroke.StrokeStyle); if (textDeviceBrush.BrushDX != null && !IsInHitTest) { RenderTarget.DrawTextLayout(new SharpDX.Vector2((float)(rect.X + textMargin + strokePixAdjust), (float)(rect.Y + textMargin + strokePixAdjust)), textLayout, textDeviceBrush.BrushDX); } } }
public override void OnRender(ChartControl chartControl, ChartScale chartScale) { if (firstTime && DrawingState == DrawingState.Normal) { firstTime = false; Cbi.License.Log("Polygon"); } RenderTarget.AntialiasMode = SharpDX.Direct2D1.AntialiasMode.PerPrimitive; Stroke outlineStroke = OutlineStroke; outlineStroke.RenderTarget = RenderTarget; ChartPanel chartPanel = chartControl.ChartPanels[PanelIndex]; // dont bother with an area brush if we're doing a hit test (software) render pass. we do not render area then. // this allows us to select something behind our area brush (like NT7) if (!IsInHitTest && AreaBrush != null) { if (areaBrushDevice.Brush == null) { Brush brushCopy = areaBrush.Clone(); brushCopy.Opacity = areaOpacity / 100d; areaBrushDevice.Brush = brushCopy; } areaBrushDevice.RenderTarget = RenderTarget; } else { areaBrushDevice.RenderTarget = null; areaBrushDevice.Brush = null; } // align to full pixel to avoid unneeded aliasing double strokePixAdjust = outlineStroke.Width % 2 == 0 ? 0.5d : 0d; // always re-create polygon geometry here SharpDX.Direct2D1.PathGeometry polyGeo = CreatePolygonGeometry(chartControl, chartPanel, chartScale, strokePixAdjust); if (DrawingState != DrawingState.Building) { if (!IsInHitTest && areaBrushDevice.BrushDX != null) { RenderTarget.FillGeometry(polyGeo, areaBrushDevice.BrushDX); } else { // Polygon can be selected by center anchor point still, so give something for the hit test pass to // detect we want to be hit test there, so draw a rect in center. actual brush doesnt matter Point[] points = GetPolygonAnchorPoints(chartControl, chartScale, true); Point centroid = points.Length > 0 ? points.Last() : new Point(); RenderTarget.FillRectangle(new SharpDX.RectangleF((float)centroid.X - 5f, (float)centroid.Y - 5f, (float)cursorSensitivity, (float)cursorSensitivity), chartControl.SelectionBrush); } } SharpDX.Direct2D1.Brush tmpBrush = IsInHitTest ? chartControl.SelectionBrush : outlineStroke.BrushDX; RenderTarget.DrawGeometry(polyGeo, tmpBrush, outlineStroke.Width, outlineStroke.StrokeStyle); polyGeo.Dispose(); }
} // End of OnMarketData protected override void OnRender(ChartControl chartControl, ChartScale chartScale) { if (Bars == null || Bars.Instrument == null || IsInHitTest) { return; } double tickSize = Bars.Instrument.MasterInstrument.TickSize; SharpDX.Direct2D1.Brush barBrush = VpBrush.ToDxBrush(RenderTarget); barBrush.Opacity = (float)(alpha / 100.0); SharpDX.Direct2D1.Brush vaBrush = VaBrush.ToDxBrush(RenderTarget); vaBrush.Opacity = (float)(alpha / 100.0); SharpDX.Direct2D1.Brush drawBrush; //For each session vol profile foreach (VolProfile vp in volProfiles) { // Get session chart xpos and width float xPos = chartControl.GetXByTime(vp.Start); float sessWidth = ((chartControl.GetXByTime(vp.End) - xPos) * (sessionWidth / (float)100.0)); // Draw each price level in session foreach (KeyValuePair <double, VolPrice> pl in vp.VolPrices) { // Price level values double vpPrice = pl.Key; long vpVol = pl.Value.Vol; // Get chart Y double priceLower = vpPrice - tickSize / 2; float yLower = chartScale.GetYByValue(priceLower); float yUpper = chartScale.GetYByValue(priceLower + tickSize); float height = Math.Max(1, Math.Abs(yUpper - yLower) - 1); // Draw bars in Value area with Value Area Brush if (EnableValueArea && (vpPrice >= vp.ValueAreaLow) && (vpPrice <= vp.ValueAreaHigh)) { drawBrush = vaBrush; } else { drawBrush = barBrush; } // Bar width float barWidth = ((float)vpVol / vp.VolPrices[vp.Poc].Vol) * sessWidth; // Draw the bar RenderTarget.FillRectangle(new SharpDX.RectangleF(xPos, yUpper, barWidth, height), drawBrush); } } barBrush.Dispose(); vaBrush.Dispose(); } // OnRender(..)
public virtual void InitializeForGraphics(RenderGraphics g) { BlackBrush = g.CreateSolidBrush(BlackColor); LightGreyFillBrush1 = g.CreateSolidBrush(LightGreyFillColor1); LightGreyFillBrush2 = g.CreateSolidBrush(LightGreyFillColor2); DarkGreyLineBrush1 = g.CreateSolidBrush(DarkGreyLineColor1); DarkGreyLineBrush2 = g.CreateSolidBrush(DarkGreyLineColor2); DarkGreyFillBrush1 = g.CreateSolidBrush(DarkGreyFillColor1); DarkGreyFillBrush2 = g.CreateSolidBrush(DarkGreyFillColor2); }
protected override void OnRender(ChartControl chartControl, ChartScale chartScale) { if (Bars == null || ChartControl == null) { return; } int barPaintWidth = Math.Max(3, 1 + 2 * ((int)ChartControl.BarWidth - 1) + 2 * shadowWidth); for (int idx = ChartBars.FromIndex; idx <= ChartBars.ToIndex; idx++) { if (idx - Displacement < 0 || idx - Displacement >= BarsArray[0].Count || (idx - Displacement < BarsRequiredToPlot)) { continue; } double valH = HAHigh.GetValueAt(idx); double valL = HALow.GetValueAt(idx); double valC = HAClose.GetValueAt(idx); double valO = HAOpen.GetValueAt(idx); int x = chartControl.GetXByBarIndex(chartControl.BarsArray[0], idx); int y1 = chartScale.GetYByValue(valO); int y2 = chartScale.GetYByValue(valH); int y3 = chartScale.GetYByValue(valL); int y4 = chartScale.GetYByValue(valC); SharpDX.Direct2D1.Brush shadowColordx = shadowColor.ToDxBrush(RenderTarget); // prepare for the color to use var xy2 = new Vector2(x, y2); var xy3 = new Vector2(x, y3); RenderTarget.DrawLine(xy2, xy3, shadowColordx, shadowWidth); if (y4 == y1) { RenderTarget.DrawLine(new Vector2(x - barPaintWidth / 2, y1), new Vector2(x + barPaintWidth / 2, y1), shadowColordx, shadowWidth); } else { if (y4 > y1) { SharpDX.Direct2D1.Brush barColorDowndx = barColorDown.ToDxBrush(RenderTarget); // prepare for the color to use RenderTarget.FillRectangle(new RectangleF(x - barPaintWidth / 2, y1, barPaintWidth, y4 - y1), barColorDowndx); barColorDowndx.Dispose(); } else { SharpDX.Direct2D1.Brush barColorUpdx = barColorUp.ToDxBrush(RenderTarget); // prepare for the color to use RenderTarget.FillRectangle(new RectangleF(x - barPaintWidth / 2, y4, barPaintWidth, y1 - y4), barColorUpdx); barColorUpdx.Dispose(); } RenderTarget.DrawRectangle(new RectangleF(x - barPaintWidth / 2 + (float)shadowWidth / 2, Math.Min(y4, y1), barPaintWidth - (float)shadowWidth, Math.Abs(y4 - y1)), shadowColordx, shadowWidth); } shadowColordx.Dispose(); } }
public override void OnRenderTargetChanged() { if (brushDx != null) { brushDx.Dispose(); } if (RenderTarget != null) { try { brushDx = Brushes.Blue.ToDxBrush(RenderTarget); } catch (Exception e) { } } }
public override void OnRenderTargetChanged() { if (textBrushDx != null) { textBrushDx.Dispose(); } if (RenderTarget != null) { try { textBrushDx = TextBrush.ToDxBrush(RenderTarget); } catch (Exception e) { } } }
private void drawRow(ChartControl chartControl, ChartScale chartScale, RowData row) { Brush brushColor = AskColor; //Determine color of this row. if (row.DataType == MarketDataType.Ask && row.Active == true) { brushColor = AskColor; } if (row.DataType == MarketDataType.Ask && row.Active == false) { brushColor = InactiveAskColor; } if (row.DataType == MarketDataType.Bid && row.Active == true) { brushColor = BidColor; } if (row.DataType == MarketDataType.Bid && row.Active == false) { brushColor = InactiveBidColor; } //Calculate Histogram width. double percentage = ((double)row.Liquidity / MyOrderBook.HighestLiquidity); double histogram = ResizableWidth * percentage; //Calculate Cell Properties double y1 = ((chartScale.GetYByValue(row.Price) + chartScale.GetYByValue(row.Price + TickSize)) / 2) + 1; double y2 = ((chartScale.GetYByValue(row.Price) + chartScale.GetYByValue(row.Price - TickSize)) / 2) - 1; SharpDX.RectangleF rect = new SharpDX.RectangleF(); rect.X = (float)chartControl.CanvasRight - Position; rect.Y = (float)y1; rect.Width = (float)-(MinimumWidth + histogram); rect.Height = (float)Math.Abs(y1 - y2); //Draw the row. using (SharpDX.Direct2D1.Brush rowBrush = brushColor.ToDxBrush(RenderTarget)) { RenderTarget.FillRectangle(rect, rowBrush); } if (rect.Height > this.MinimumTextHeight) { RenderTarget.DrawText(string.Format("{0}", row.Liquidity), textFormat, rect, TextColor.ToDxBrush(RenderTarget)); } }
/// <summary> /// Updates device dependent resources for when RenderTarget changes. /// </summary> /// <param name="renderTarget">The hosting NinjaScript's RenderTarget</param> public void RenderTargetChange(SharpDX.Direct2D1.RenderTarget renderTarget) { if (renderTarget == null || renderTarget.IsDisposed) { return; } if (dxBrush != null) { dxBrush.Dispose(); } if (mediaBrush != null) { dxBrush = mediaBrush.ToDxBrush(renderTarget); } }
protected override void OnRenderInitialized(RenderGraphics g) { theme = RenderTheme.CreateResourcesForGraphics(g); bmpTracks[Channel.Square1] = g.CreateBitmapFromResource("Square"); bmpTracks[Channel.Square2] = g.CreateBitmapFromResource("Square"); bmpTracks[Channel.Triangle] = g.CreateBitmapFromResource("Triangle"); bmpTracks[Channel.Noise] = g.CreateBitmapFromResource("Noise"); bmpTracks[Channel.DPCM] = g.CreateBitmapFromResource("DPCM"); bmpGhostNote = g.CreateBitmapFromResource("GhostSmall"); playPositionBrush = g.CreateSolidBrush(Color.FromArgb(192, ThemeBase.LightGreyFillColor1)); whiteKeyBrush = g.CreateHorizontalGradientBrush(0, trackNameSizeX, ThemeBase.LightGreyFillColor1, ThemeBase.LightGreyFillColor2); patternHeaderBrush = g.CreateVerticalGradientBrush(0, patternHeaderSizeY, ThemeBase.LightGreyFillColor1, ThemeBase.LightGreyFillColor2); selectedPatternBrush = g.CreateSolidBrush(Color.FromArgb(128, ThemeBase.LightGreyFillColor1)); }
public virtual void InitializeForGraphics(RenderGraphics g) { BlackBrush = g.CreateSolidBrush(BlackColor); LightGreyFillBrush1 = g.CreateSolidBrush(LightGreyFillColor1); LightGreyFillBrush2 = g.CreateSolidBrush(LightGreyFillColor2); DarkGreyLineBrush1 = g.CreateSolidBrush(DarkGreyLineColor1); DarkGreyLineBrush2 = g.CreateSolidBrush(DarkGreyLineColor2); DarkGreyFillBrush1 = g.CreateSolidBrush(DarkGreyFillColor1); DarkGreyFillBrush2 = g.CreateSolidBrush(DarkGreyFillColor2); for (int j = 0; j < CustomColors.GetLength(1); j++) { for (int i = 0; i < CustomColors.GetLength(0); i++) { CustomColorBrushes[CustomColors[i, j]] = g.CreateSolidBrush(CustomColors[i, j]); } } }
/// <summary> /// Updates the Media Bursh and SharpDX Brush also changing opacity. /// </summary> /// <param name="owner">The hosting NinjaScript's RenderTarget</param> /// <param name="owner">The new Media Brush to use</param> /// <param name="owner">The new Opacity to use</param> public void UpdateBrush(SharpDX.Direct2D1.RenderTarget renderTarget, Brush newMediaBrush, double newOpacity) { // Set Media Brush to brush passed mediaBrush = newMediaBrush; // Call SetOpacity() to clone, set opacity and freeze brush. SetOpacity(newOpacity); // Dispose DX Brushes and other Device Dependant resources if (dxBrush != null) { dxBrush.Dispose(); } // Recreate DX Brushes and other Device Dependant Resources here, making sure RenderTarget is not null or IsDisposed if (renderTarget != null && !renderTarget.IsDisposed) { dxBrush = mediaBrush.ToDxBrush(renderTarget); } }
public void DrawGlyphRuns(SharpDX.Direct2D1.WindowRenderTarget renderTarget, SharpDX.Direct2D1.Brush brush) { // Just iterate through all the saved glyph runs // and have DWrite to draw each one. for (int i = 0; i < glyphRuns_.Count; i++) { CustomGlyphRun customGlyphRun = glyphRuns_[i]; if (customGlyphRun.glyphCount == 0) { continue; } GlyphRun glyphRun = customGlyphRun.Convert(glyphIndices_, glyphAdvances_, glyphOffsets_); if (glyphRun != null) { renderTarget.DrawGlyphRun(new System.Drawing.PointF(customGlyphRun.x, customGlyphRun.y), ref glyphRun, brush, MeasuringMode.Natural); } } }
public override void OnRender(ChartControl chartControl, ChartScale chartScale) { Stroke.RenderTarget = RenderTarget; // first of all, turn on anti-aliasing to smooth out our line RenderTarget.AntialiasMode = SharpDX.Direct2D1.AntialiasMode.PerPrimitive; ChartPanel panel = chartControl.ChartPanels[chartScale.PanelIndex]; Point startPoint = StartAnchor.GetPoint(chartControl, panel, chartScale); // align to full pixel to avoid unneeded aliasing double strokePixAdj = Stroke.Width % 2 == 0 ? 0.5d : 0d; Vector pixelAdjustVec = new Vector(strokePixAdj, strokePixAdj); Point endPoint = EndAnchor.GetPoint(chartControl, panel, chartScale); // convert our start / end pixel points to directx 2d vectors Point startPointAdjusted = startPoint + pixelAdjustVec; Point endPointAdjusted = endPoint + pixelAdjustVec; SharpDX.Vector2 startVec = startPointAdjusted.ToVector2(); SharpDX.Vector2 endVec = endPointAdjusted.ToVector2(); SharpDX.Direct2D1.Brush tmpBrush = IsInHitTest ? chartControl.SelectionBrush : Stroke.BrushDX; // if a plain ol' line, then we're all done // if we're an arrow line, make sure to draw the actual line. for extended lines, only a single // line to extended points is drawn below, to avoid unneeded multiple DrawLine calls RenderTarget.DrawLine(startVec, endVec, tmpBrush, Stroke.Width, Stroke.StrokeStyle); // we have a line type with extensions (ray / extended line) or additional drawing needed // create a line vector to easily calculate total length Vector lineVector = endPoint - startPoint; lineVector.Normalize(); Point minPoint = startPointAdjusted; Point maxPoint = GetExtendedPoint(chartControl, panel, chartScale, StartAnchor, EndAnchor); //GetExtendedPoint(startPoint, endPoint); // RenderTarget.DrawLine(endPointAdjusted.ToVector2(), maxPoint.ToVector2(), tmpBrush, Stroke.Width, Stroke.StrokeStyle); }
public override void OnRenderTargetChanged() { base.OnRenderTargetChanged(); if (RenderTarget == null) { return; } if (offScreenDXBrush != null) { offScreenDXBrush.Dispose(); } offScreenDXBrush = offScreenMediaBrush.ToDxBrush(RenderTarget); if (backgroundDXBrush != null) { backgroundDXBrush.Dispose(); } backgroundDXBrush = backgroundMediaBrush.ToDxBrush(RenderTarget); backgroundDXBrush.Opacity = (float)AreaOpacity / 100f; }
public override void OnRenderTargetChanged() { if (askBrush != null) { askBrush.Dispose(); } if (bidBrush != null) { bidBrush.Dispose(); } if (lastBrush != null) { lastBrush.Dispose(); } if (RenderTarget != null) { askBrush = AskStroke.Brush.ToDxBrush(RenderTarget); bidBrush = BidStroke.Brush.ToDxBrush(RenderTarget); lastBrush = LastStroke.Brush.ToDxBrush(RenderTarget); } }
protected override void OnRenderInitialized(RenderGraphics g) { theme = RenderTheme.CreateResourcesForGraphics(g); toolbarBrush = g.CreateHorizontalGradientBrush(0, 81, ThemeBase.LightGreyFillColor1, ThemeBase.LightGreyFillColor2); bmpLoopNone = g.CreateBitmapFromResource("LoopNone"); bmpLoopSong = g.CreateBitmapFromResource("Loop"); bmpLoopPattern = g.CreateBitmapFromResource("LoopPattern"); bmpPlay = g.CreateBitmapFromResource("Play"); bmpPause = g.CreateBitmapFromResource("Pause"); buttons[ButtonNew] = new Button { X = 4, Y = 4, Bmp = g.CreateBitmapFromResource("File"), Click = OnNew }; buttons[ButtonOpen] = new Button { X = 44, Y = 4, Bmp = g.CreateBitmapFromResource("Open"), Click = OnOpen }; buttons[ButtonSave] = new Button { X = 84, Y = 4, Bmp = g.CreateBitmapFromResource("Save"), Click = OnSave, RightClick = OnSaveAs }; buttons[ButtonExport] = new Button { X = 124, Y = 4, Bmp = g.CreateBitmapFromResource("Export"), Click = OnExport }; buttons[ButtonUndo] = new Button { X = 164, Y = 4, Bmp = g.CreateBitmapFromResource("Undo"), Click = OnUndo, Enabled = OnUndoEnabled }; buttons[ButtonRedo] = new Button { X = 204, Y = 4, Bmp = g.CreateBitmapFromResource("Redo"), Click = OnRedo, Enabled = OnRedoEnabled }; buttons[ButtonConfig] = new Button { X = 244, Y = 4, Bmp = g.CreateBitmapFromResource("Config"), Click = OnConfig }; buttons[ButtonPlay] = new Button { X = 476, Y = 4, Click = OnPlay, GetBitmap = OnPlayGetBitmap }; buttons[ButtonRewind] = new Button { X = 516, Y = 4, Bmp = g.CreateBitmapFromResource("Rewind"), Click = OnRewind }; buttons[ButtonLoop] = new Button { X = 556, Y = 4, Click = OnLoop, GetBitmap = OnLoopGetBitmap }; buttons[ButtonNew].ToolTip = "New Project (Ctrl-N)"; buttons[ButtonOpen].ToolTip = "Open Project (Ctrl-O)"; buttons[ButtonSave].ToolTip = "Save Project (Ctrl-S) [Right-Click: Save As...]"; buttons[ButtonExport].ToolTip = "Export to various formats (Ctrl+E)"; buttons[ButtonUndo].ToolTip = "Undo (Ctrl+Z)"; buttons[ButtonRedo].ToolTip = "Redo (Ctrl+Y)"; buttons[ButtonConfig].ToolTip = "Edit Application Settings"; buttons[ButtonPlay].ToolTip = "Play/Pause (Space) [Ctrl+Space: Play pattern loop, Shift-Space: Play song loop]"; buttons[ButtonRewind].ToolTip = "Rewind (Home) [Ctrl+Home: Rewind to beginning of current pattern]"; buttons[ButtonLoop].ToolTip = "Toggle Loop Mode"; var scaling = RenderTheme.MainWindowScaling; for (int i = 0; i < ButtonCount; i++) { var btn = buttons[i]; btn.X = (int)(btn.X * scaling); btn.Y = (int)(btn.Y * scaling); btn.Size = (int)(btn.Size * scaling); } timecodePosX = (int)(DefaultTimecodePosX * scaling); timecodePosY = (int)(DefaultTimecodePosY * scaling); timecodeSizeX = (int)(DefaultTimecodeSizeX * scaling); timecodeTextPosX = (int)(DefaultTimecodeTextPosX * scaling); tooltipPosY = (int)(DefaultTooltipPosY * scaling); }
public override void OnRender(ChartControl chartControl, ChartScale chartScale) { //Allow user to change ZOrder when manually drawn on chart if (!hasSetZOrder && !StartAnchor.IsNinjaScriptDrawn) { ZOrderType = DrawingToolZOrder.Normal; ZOrder = ChartPanel.ChartObjects.Min(z => z.ZOrder) - 1; hasSetZOrder = true; } RenderTarget.AntialiasMode = SharpDX.Direct2D1.AntialiasMode.PerPrimitive; OutlineStroke.RenderTarget = RenderTarget; ChartPanel chartPanel = chartControl.ChartPanels[PanelIndex]; // recenter region anchors to always be onscreen/centered double middleX = chartPanel.X + chartPanel.W / 2d; double middleY = chartPanel.Y + chartPanel.H / 2d; if (Mode == RegionHighlightMode.Price) { StartAnchor.UpdateXFromPoint(new Point(middleX, 0), chartControl, chartScale); EndAnchor.UpdateXFromPoint(new Point(middleX, 0), chartControl, chartScale); } else { StartAnchor.UpdateYFromDevicePoint(new Point(0, middleY), chartScale); EndAnchor.UpdateYFromDevicePoint(new Point(0, middleY), chartScale); } Point startPoint = StartAnchor.GetPoint(chartControl, chartPanel, chartScale); Point endPoint = EndAnchor.GetPoint(chartControl, chartPanel, chartScale); double width = endPoint.X - startPoint.X; AnchorLineStroke.RenderTarget = RenderTarget; OutlineStroke.RenderTarget = RenderTarget; if (!IsInHitTest && AreaBrush != null) { if (areaBrushDevice.Brush == null) { Brush brushCopy = areaBrush.Clone(); brushCopy.Opacity = areaOpacity / 100d; areaBrushDevice.Brush = brushCopy; } areaBrushDevice.RenderTarget = RenderTarget; } else { areaBrushDevice.RenderTarget = null; areaBrushDevice.Brush = null; } // align to full pixel to avoid unneeded aliasing float strokePixAdjust = Math.Abs(OutlineStroke.Width % 2d).ApproxCompare(0) == 0 ? 0.5f : 0f; SharpDX.RectangleF rect = Mode == RegionHighlightMode.Time ? new SharpDX.RectangleF((float)startPoint.X + strokePixAdjust, ChartPanel.Y - OutlineStroke.Width + strokePixAdjust, (float)width, chartPanel.Y + chartPanel.H + OutlineStroke.Width * 2) : new SharpDX.RectangleF(chartPanel.X - OutlineStroke.Width + strokePixAdjust, (float)startPoint.Y + strokePixAdjust, chartPanel.X + chartPanel.W + OutlineStroke.Width * 2, (float)(endPoint.Y - startPoint.Y)); if (!IsInHitTest && areaBrushDevice.BrushDX != null) { RenderTarget.FillRectangle(rect, areaBrushDevice.BrushDX); } SharpDX.Direct2D1.Brush tmpBrush = IsInHitTest ? chartControl.SelectionBrush : OutlineStroke.BrushDX; RenderTarget.DrawRectangle(rect, tmpBrush, OutlineStroke.Width, OutlineStroke.StrokeStyle); if (IsSelected) { tmpBrush = IsInHitTest ? chartControl.SelectionBrush : AnchorLineStroke.BrushDX; RenderTarget.DrawLine(startPoint.ToVector2(), endPoint.ToVector2(), tmpBrush, AnchorLineStroke.Width, AnchorLineStroke.StrokeStyle); } }
protected override void OnRender(ChartControl chartControl, ChartScale chartScale) { if (IsInHitTest) { return; } int lastBar = ChartBars.ToIndex; int firstBar = ChartBars.FromIndex; double highPrice = 0; double lowPrice = double.MaxValue; SharpDX.Direct2D1.Brush brushDown = BarDownBrush.ToDxBrush(RenderTarget); SharpDX.Direct2D1.Brush lineBrush = LineBrush.ToDxBrush(RenderTarget); SharpDX.Direct2D1.Brush brushUp = BarUpBrush.ToDxBrush(RenderTarget); brushDown.Opacity = (float)(Opacity / 100.0); brushUp.Opacity = (float)(Opacity / 100.0); for (int idx = firstBar; idx <= lastBar && idx >= 0; idx++) { highPrice = Math.Max(highPrice, Bars.GetHigh(idx)); lowPrice = Math.Min(lowPrice, Bars.GetLow(idx)); } int volumeBarCount = BarCount; double priceRange = highPrice - lowPrice; double priceBoxSize = priceRange / volumeBarCount; double volumeMax = 0; // Pass 1: Fill all VolumeInfo structures with appropriate data for (int i = 0; i < volumeBarCount; i++) { double priceUpper = lowPrice + priceBoxSize * (i + 1); double priceLower = lowPrice + priceBoxSize * i; double priceVolumeUp = 0; double priceVolumeDown = 0; for (int idx = firstBar; idx <= lastBar; idx++) { double checkPrice; PriceSeries series = (Inputs[0] as PriceSeries); switch (series.PriceType) { case PriceType.Open: checkPrice = Bars.GetOpen(idx); break; case PriceType.Close: checkPrice = Bars.GetClose(idx); break; case PriceType.High: checkPrice = Bars.GetHigh(idx); break; case PriceType.Low: checkPrice = Bars.GetLow(idx); break; case PriceType.Median: checkPrice = (Bars.GetHigh(idx) + Bars.GetLow(idx)) / 2; break; case PriceType.Typical: checkPrice = (Bars.GetHigh(idx) + Bars.GetLow(idx) + Bars.GetClose(idx)) / 3; break; case PriceType.Weighted: checkPrice = (Bars.GetHigh(idx) + Bars.GetLow(idx) + 2 * Bars.GetClose(idx)) / 4; break; default: checkPrice = Bars.GetClose(idx); break; } if (checkPrice >= priceLower && checkPrice < priceUpper) { if (Bars.GetOpen(idx) < Bars.GetClose(idx)) { priceVolumeUp += Bars.GetVolume(idx); } else { priceVolumeDown += Bars.GetVolume(idx); } } } volumeInfo[i].up = priceVolumeUp; volumeInfo[i].down = priceVolumeDown; volumeInfo[i].total = priceVolumeUp + priceVolumeDown; volumeMax = Math.Max(volumeMax, volumeInfo[i].total); } // Pass 2: Paint the volume bars for (int i = 0; i < Math.Min(volumeBarCount, lastBar - firstBar + 1); i++) { double priceUpper = lowPrice + priceBoxSize * (i + 1); double priceLower = lowPrice + priceBoxSize * i; int yUpper = Convert.ToInt32(chartScale.GetYByValue(priceUpper)) + BarSpacing; int yLower = Convert.ToInt32(chartScale.GetYByValue(priceLower)); int barWidthUp = (int)((chartScale.Height / 2) * (volumeInfo[i].up / volumeMax)); int barWidthDown = (int)((chartScale.Height / 2) * (volumeInfo[i].down / volumeMax)); SharpDX.RectangleF rect = new SharpDX.RectangleF(ChartPanel.X, yUpper, barWidthUp, Math.Abs(yUpper - yLower)); RenderTarget.FillRectangle(rect, brushUp); RenderTarget.DrawRectangle(rect, brushUp); SharpDX.RectangleF rect2 = new SharpDX.RectangleF(ChartPanel.X + barWidthUp, yUpper, barWidthDown, Math.Abs(yUpper - yLower)); RenderTarget.DrawRectangle(rect2, brushDown); RenderTarget.FillRectangle(rect2, brushDown); if (DrawLines) { RenderTarget.DrawLine(new SharpDX.Vector2(ChartPanel.X, yLower), new SharpDX.Vector2(ChartPanel.X + ChartPanel.W, yLower), lineBrush); if (i == volumeBarCount - 1) { RenderTarget.DrawLine(new SharpDX.Vector2(ChartPanel.X, yUpper), new SharpDX.Vector2(ChartPanel.X + ChartPanel.W, yUpper), lineBrush); } } } lineBrush.Dispose(); brushDown.Dispose(); brushUp.Dispose(); }
protected override void OnRender(ChartControl chartControl, ChartScale chartScale) { if (Bars == null || Bars.Instrument == null || IsInHitTest) { return; } int firstBarIdxToPaint = -1; double tickSize = Bars.Instrument.MasterInstrument.TickSize; double volumeMax = 0; SharpDX.Direct2D1.Brush upBrush = VolumeUpBrush.ToDxBrush(RenderTarget); SharpDX.Direct2D1.Brush downBrush = VolumeDownBrush.ToDxBrush(RenderTarget); SharpDX.Direct2D1.Brush neutralBrush = VolumeNeutralBrush.ToDxBrush(RenderTarget); SharpDX.Direct2D1.Brush lineBrushDx = LineBrush.ToDxBrush(RenderTarget); upBrush.Opacity = (float)(alpha / 100.0); downBrush.Opacity = (float)(alpha / 100.0); neutralBrush.Opacity = (float)(alpha / 100.0); for (int i = newSessionBarIdx.Count - 1; i >= 0; i--) { int prevSessionBreakIdx = newSessionBarIdx[i]; if (prevSessionBreakIdx <= ChartBars.ToIndex) { startIndexOf = newSessionBarIdx.IndexOf(prevSessionBreakIdx); firstBarIdxToPaint = prevSessionBreakIdx; break; } } if (sortedDicList.Count < 1 && cacheDictionary.Keys.Count > 0) { sortedDicList.Add(cacheDictionary); } foreach (Dictionary <double, VolumeInfoItem> tmpDict in sortedDicList) { foreach (KeyValuePair <double, VolumeInfoItem> keyValue in tmpDict) { double price = keyValue.Key; if (Bars.BarsType.IsIntraday && (price > chartScale.MaxValue || price < chartScale.MinValue)) { continue; } VolumeInfoItem vii = keyValue.Value; double total = vii.up + vii.down + vii.neutral; volumeMax = Math.Max(volumeMax, total); } } if (volumeMax.ApproxCompare(0) == 0) { return; } int viiPositions = 0; foreach (KeyValuePair <double, VolumeInfoItem> keyValue in sortedDicList[startIndexOf]) { viiPositions++; VolumeInfoItem vii = keyValue.Value; double priceLower = keyValue.Key - tickSize / 2; float yLower = chartScale.GetYByValue(priceLower); float yUpper = chartScale.GetYByValue(priceLower + tickSize); float height = Math.Max(1, Math.Abs(yUpper - yLower) - barSpacing); int barWidthUp = (int)((ChartPanel.W / 2) * (vii.up / volumeMax)); int barWidthNeutral = (int)((ChartPanel.W / 2) * (vii.neutral / volumeMax)); int barWidthDown = (int)((ChartPanel.W / 2) * (vii.down / volumeMax)); float stationaryXpos = chartControl.GetXByBarIndex(ChartBars, !Bars.IsTickReplay ? ChartBars.FromIndex : Math.Max(ChartBars.FromIndex, firstBarIdxToPaint)); float xpos = chartControl.GetXByBarIndex(ChartBars, !Bars.IsTickReplay ? ChartBars.FromIndex : Math.Max(1, Math.Max(ChartBars.FromIndex, firstBarIdxToPaint)) - 1); RenderTarget.FillRectangle(new SharpDX.RectangleF(xpos, yUpper, barWidthUp, height), upBrush); xpos += barWidthUp; RenderTarget.FillRectangle(new SharpDX.RectangleF(xpos, yUpper, barWidthNeutral, height), neutralBrush); xpos += barWidthNeutral; RenderTarget.FillRectangle(new SharpDX.RectangleF(xpos, yUpper, barWidthDown, height), downBrush); if (!drawLines) { continue; } // Lower line RenderTarget.DrawLine(new SharpDX.Vector2(stationaryXpos, yLower), new SharpDX.Vector2((ChartPanel.X + ChartPanel.W), yLower), lineBrushDx); // Upper line (only at very top) if (viiPositions == sortedDicList[startIndexOf].Count) { RenderTarget.DrawLine(new SharpDX.Vector2(stationaryXpos, yUpper), new SharpDX.Vector2((ChartPanel.X + ChartPanel.W), yUpper), lineBrushDx); } } lineBrushDx.Dispose(); upBrush.Dispose(); downBrush.Dispose(); neutralBrush.Dispose(); }
public override void OnRender(ChartControl chartControl, ChartScale chartScale) { if (firstTime && DrawingState == DrawingState.Normal) { firstTime = false; Cbi.License.Log("Path"); } RenderTarget.AntialiasMode = SharpDX.Direct2D1.AntialiasMode.PerPrimitive; Stroke outlineStroke = OutlineStroke; outlineStroke.RenderTarget = RenderTarget; ChartPanel chartPanel = chartControl.ChartPanels[PanelIndex]; double strokePixAdjust = outlineStroke.Width % 2 == 0 ? 0.5d : 0d; Vector pixelAdjustVec = new Vector(strokePixAdjust, strokePixAdjust); SharpDX.Direct2D1.PathGeometry polyGeo = CreatePathGeometry(chartControl, chartPanel, chartScale, strokePixAdjust); SharpDX.Direct2D1.Brush tmpBrush = IsInHitTest ? chartControl.SelectionBrush : outlineStroke.BrushDX; RenderTarget.DrawGeometry(polyGeo, tmpBrush, outlineStroke.Width, outlineStroke.StrokeStyle); polyGeo.Dispose(); if (PathBegin == PathToolCapMode.Arrow || PathEnd == PathToolCapMode.Arrow) { Point[] points = GetPathAnchorPoints(chartControl, chartScale); if (points.Length > 1) { if (arrowPathGeometry == null) { arrowPathGeometry = new SharpDX.Direct2D1.PathGeometry(Core.Globals.D2DFactory); SharpDX.Direct2D1.GeometrySink geometrySink = arrowPathGeometry.Open(); float arrowWidth = 6f; SharpDX.Vector2 top = new SharpDX.Vector2(0, outlineStroke.Width * 0.5f); geometrySink.BeginFigure(top, SharpDX.Direct2D1.FigureBegin.Filled); geometrySink.AddLine(new SharpDX.Vector2(arrowWidth, -arrowWidth)); geometrySink.AddLine(new SharpDX.Vector2(-arrowWidth, -arrowWidth)); geometrySink.AddLine(top); // cap off figure geometrySink.EndFigure(SharpDX.Direct2D1.FigureEnd.Closed); geometrySink.Close(); } if (PathBegin == PathToolCapMode.Arrow) { Vector lineVector = points[0] - points[1]; lineVector.Normalize(); Point pointAdjusted = points[0] + pixelAdjustVec; SharpDX.Vector2 pointVec = pointAdjusted.ToVector2(); float vectorAngle = -(float)Math.Atan2(lineVector.X, lineVector.Y); Vector adjustVector = lineVector * 5; SharpDX.Vector2 arrowPointVec = new SharpDX.Vector2((float)(pointVec.X + adjustVector.X), (float)(pointVec.Y + adjustVector.Y)); SharpDX.Matrix3x2 transformMatrix2 = SharpDX.Matrix3x2.Rotation(vectorAngle, SharpDX.Vector2.Zero) * SharpDX.Matrix3x2.Scaling((float)Math.Max(1.0f, outlineStroke.Width * .45) + 0.25f) * SharpDX.Matrix3x2.Translation(arrowPointVec); RenderTarget.Transform = transformMatrix2; RenderTarget.FillGeometry(arrowPathGeometry, tmpBrush); RenderTarget.Transform = SharpDX.Matrix3x2.Identity; } if (PathEnd == PathToolCapMode.Arrow) { Vector lineVector = points[points.Length - 1] - points[points.Length - 2]; lineVector.Normalize(); Point pointAdjusted = points[points.Length - 1] + pixelAdjustVec; SharpDX.Vector2 pointVec = pointAdjusted.ToVector2(); float vectorAngle = -(float)Math.Atan2(lineVector.X, lineVector.Y); Vector adjustVector = lineVector * 5; SharpDX.Vector2 arrowPointVec = new SharpDX.Vector2((float)(pointVec.X + adjustVector.X), (float)(pointVec.Y + adjustVector.Y)); SharpDX.Matrix3x2 transformMatrix2 = SharpDX.Matrix3x2.Rotation(vectorAngle, SharpDX.Vector2.Zero) * SharpDX.Matrix3x2.Scaling((float)Math.Max(1.0f, outlineStroke.Width * .45) + 0.25f) * SharpDX.Matrix3x2.Translation(arrowPointVec); RenderTarget.Transform = transformMatrix2; RenderTarget.FillGeometry(arrowPathGeometry, tmpBrush); RenderTarget.Transform = SharpDX.Matrix3x2.Identity; } } } if (ShowCount) { SimpleFont wpfFont = chartControl.Properties.LabelFont ?? new SimpleFont(); SharpDX.DirectWrite.TextFormat textFormat = wpfFont.ToDirectWriteTextFormat(); textFormat.TextAlignment = SharpDX.DirectWrite.TextAlignment.Leading; textFormat.WordWrapping = SharpDX.DirectWrite.WordWrapping.NoWrap; for (int i = 1; i < ChartAnchors.Count; i++) { Point p = ChartAnchors[i - 1].GetPoint(chartControl, chartPanel, chartScale); Point p1 = ChartAnchors[i].GetPoint(chartControl, chartPanel, chartScale); if (i + 1 < ChartAnchors.Count) { Point p2 = ChartAnchors[i + 1].GetPoint(chartControl, chartPanel, chartScale); Vector v1 = p - p1; v1.Normalize(); Vector v2 = p2 - p1; v2.Normalize(); Vector vector = v1 + v2; vector.Normalize(); SharpDX.DirectWrite.TextLayout textLayout = new SharpDX.DirectWrite.TextLayout(Core.Globals.DirectWriteFactory, i.ToString(), textFormat, 250, textFormat.FontSize); Point textPoint = p1 - vector * textFormat.FontSize; textPoint.X -= textLayout.Metrics.Width / 2f; textPoint.Y -= textLayout.Metrics.Height / 2f; RenderTarget.DrawTextLayout((textPoint + pixelAdjustVec).ToVector2(), textLayout, outlineStroke.BrushDX, SharpDX.Direct2D1.DrawTextOptions.NoSnap); textLayout.Dispose(); } else { SharpDX.DirectWrite.TextLayout textLayout = new SharpDX.DirectWrite.TextLayout(Core.Globals.DirectWriteFactory, i.ToString(), textFormat, 250, textFormat.FontSize); Vector vector = (p - p1); vector.Normalize(); Point textPoint = p1 - vector * textFormat.FontSize; textPoint.X -= textLayout.Metrics.Width / 2f; textPoint.Y -= textLayout.Metrics.Height / 2f; RenderTarget.DrawTextLayout((textPoint + pixelAdjustVec).ToVector2(), textLayout, outlineStroke.BrushDX, SharpDX.Direct2D1.DrawTextOptions.NoSnap); textLayout.Dispose(); } } textFormat.Dispose(); } }
private void DrawTextBox(bool Snap, string displayText, double x, double y, SharpDX.Direct2D1.Brush brush, SharpDX.Direct2D1.Brush bgBrush, Stroke stroke, float rotate) { const int padding = 4; // Text has changed, need to update cached TextLayout if (displayText != lastText) { needsLayoutUpdate = true; } lastText = displayText; // Update cachedTextLayout if (needsLayoutUpdate || cachedTextLayout == null) { SharpDX.DirectWrite.TextFormat textFormat = Font.ToDirectWriteTextFormat(); cachedTextLayout = new SharpDX.DirectWrite.TextLayout(NinjaTrader.Core.Globals.DirectWriteFactory, displayText, textFormat, ChartPanel.X + ChartPanel.W, textFormat.FontSize); textFormat.Dispose(); needsLayoutUpdate = false; } // Snap TextBox coordinates to ChartPanel when out of bounds if (Snap) { if (rotate == 1.5708f) { y = Math.Max(ChartPanel.Y + cachedTextLayout.Metrics.Width + 2 * padding, y); } else { y = Math.Min(ChartPanel.H - padding, y); y = Math.Max(ChartPanel.Y + cachedTextLayout.Metrics.Height + padding, y); x = Math.Max(ChartPanel.X + cachedTextLayout.Metrics.Width + 2 * padding, x); } } // Apply rotation RenderTarget.Transform = SharpDX.Matrix3x2.Rotation(rotate, new SharpDX.Vector2((float)x, (float)y)); // Add padding to TextPlotPoint SharpDX.Vector2 TextPlotPoint = new System.Windows.Point(x - cachedTextLayout.Metrics.Width - padding / 2, y - cachedTextLayout.Metrics.Height).ToVector2(); // Draw the TextBox if (displayText.Length > 0) { SharpDX.RectangleF PLBoundRect = new SharpDX.RectangleF((float)x - cachedTextLayout.Metrics.Width - padding, (float)y - cachedTextLayout.Metrics.Height - padding / 2, cachedTextLayout.Metrics.Width + padding, cachedTextLayout.Metrics.Height + padding); SharpDX.Direct2D1.RoundedRectangle PLRoundedRect = new SharpDX.Direct2D1.RoundedRectangle() { Rect = PLBoundRect, RadiusX = cachedTextLayout.FontSize / 4, RadiusY = cachedTextLayout.FontSize / 4 }; RenderTarget.FillRoundedRectangle(PLRoundedRect, bgBrush); RenderTarget.DrawRoundedRectangle(PLRoundedRect, stroke.BrushDX, stroke.Width, stroke.StrokeStyle); // Draw the TextLayout RenderTarget.DrawTextLayout(TextPlotPoint, cachedTextLayout, brush, SharpDX.Direct2D1.DrawTextOptions.NoSnap); } // Restore rotation RenderTarget.Transform = SharpDX.Matrix3x2.Identity; }
/* Steps: * 1. Project start/end points for rays and extended lines * 2. Find collitions with ChartPanel for TextBox coordinates * 3. Determine price to be appended * 4. Create message * 5. Draw TextBox */ public override void OnRender(ChartControl chartControl, ChartScale chartScale) { base.OnRender(chartControl, chartScale); Stroke.RenderTarget = RenderTarget; OutlineStroke.RenderTarget = RenderTarget; bool snap = true; bool startsOnScreen = true; bool priceOffScreen = false; double priceToUse = 0; string pricetime = String.Empty; string TextToDisplay = DisplayText; MasterInstrument masterInst = GetAttachedToChartBars().Bars.Instrument.MasterInstrument; Point startPoint = StartAnchor.GetPoint(chartControl, ChartPanel, chartScale); Point endPoint = EndAnchor.GetPoint(chartControl, ChartPanel, chartScale); double strokePixAdj = ((double)(Stroke.Width % 2)).ApproxCompare(0) == 0 ? 0.5d : 0d; Vector pixelAdjustVec = new Vector(strokePixAdj, strokePixAdj); Point startAdj = (LineType == ChartLineType.HorizontalLine ? new Point(ChartPanel.X, startPoint.Y) : new Point(startPoint.X, ChartPanel.Y)) + pixelAdjustVec; Point endAdj = (LineType == ChartLineType.HorizontalLine ? new Point(ChartPanel.X + ChartPanel.W, startPoint.Y) : new Point(startPoint.X, ChartPanel.Y + ChartPanel.H)) + pixelAdjustVec; Vector distVec = Vector.Divide(Point.Subtract(endPoint, startPoint), 100); Vector scalVec = (LineType == ChartLineType.ExtendedLine || LineType == ChartLineType.Ray || LineType == ChartLineType.HorizontalLine) ? Vector.Multiply(distVec, 10000) : Vector.Multiply(distVec, 100); Point extPoint = Vector.Add(scalVec, startPoint); // Project extended line start point if it is off screen if (LineType == ChartLineType.ExtendedLine && TextDisplayMode != TextMode.EndPoint) { startPoint = Point.Subtract(startPoint, scalVec); } // Project TextBox coordinate for extended lines and rays to get ChartPanel bounds if (LineType == ChartLineType.ExtendedLine || LineType == ChartLineType.Ray) { extPoint = Vector.Add(scalVec, extPoint); } // Find collisions with ChartPanel bounds for PriceScale bound TextBox coordinates if (LineType == ChartLineType.HorizontalLine || LineType == ChartLineType.VerticalLine) { extPoint = endAdj; startPoint = startAdj; } else if (TextDisplayMode == TextMode.EndPoint) { extPoint = endPoint; snap = false; } else { if (extPoint.X <= ChartPanel.X || extPoint.Y < ChartPanel.Y || extPoint.X > ChartPanel.W || extPoint.Y > ChartPanel.H) { switch (LineIntersectsRect(startPoint, extPoint, new SharpDX.RectangleF(ChartPanel.X, ChartPanel.Y, ChartPanel.W, ChartPanel.H))) { case RectSide.Top: extPoint = FindIntersection(startPoint, extPoint, new Point(ChartPanel.X, ChartPanel.Y), new Point(ChartPanel.W, ChartPanel.Y)); break; case RectSide.Bottom: extPoint = FindIntersection(startPoint, extPoint, new Point(ChartPanel.W, ChartPanel.H), new Point(ChartPanel.X, ChartPanel.H)); break; case RectSide.Left: extPoint = FindIntersection(startPoint, extPoint, new Point(ChartPanel.X, ChartPanel.H), new Point(ChartPanel.X, ChartPanel.Y)); break; case RectSide.Right: extPoint = FindIntersection(startPoint, extPoint, new Point(ChartPanel.W, ChartPanel.Y), new Point(ChartPanel.W, ChartPanel.H)); break; default: return; } } if (startPoint.X <= ChartPanel.X || startPoint.Y < ChartPanel.Y || startPoint.X > ChartPanel.W || startPoint.Y > ChartPanel.H) { switch (LineIntersectsRect(extPoint, startPoint, new SharpDX.RectangleF(ChartPanel.X, ChartPanel.Y, ChartPanel.W, ChartPanel.H))) { case RectSide.Top: startPoint = FindIntersection(extPoint, startPoint, new Point(ChartPanel.X, ChartPanel.Y), new Point(ChartPanel.W, ChartPanel.Y)); break; case RectSide.Bottom: startPoint = FindIntersection(extPoint, startPoint, new Point(ChartPanel.W, ChartPanel.H), new Point(ChartPanel.X, ChartPanel.H)); break; case RectSide.Left: startPoint = FindIntersection(extPoint, startPoint, new Point(ChartPanel.X, ChartPanel.H), new Point(ChartPanel.X, ChartPanel.Y)); break; case RectSide.Right: startPoint = FindIntersection(extPoint, startPoint, new Point(ChartPanel.W, ChartPanel.Y), new Point(ChartPanel.W, ChartPanel.H)); break; default: return; } } if (endPoint.X <= ChartPanel.X || endPoint.Y < ChartPanel.Y || endPoint.X > ChartPanel.W || endPoint.Y > ChartPanel.H) { priceOffScreen = true; } } // Scale coordinates by HorizontalOffset/VerticalOffset distVec = Point.Subtract(extPoint, startPoint); scalVec = Vector.Multiply(Vector.Divide(distVec, 100), HorizontalOffset); extPoint = Point.Subtract(extPoint, scalVec); extPoint.Y -= VerticalOffset; // Get a Price or a Timestamp to append to the label switch (LineType) { case ChartLineType.VerticalLine: pricetime = StartAnchor.Time.ToString(); break; case ChartLineType.HorizontalLine: priceToUse = StartAnchor.Price; break; case ChartLineType.ExtendedLine: case ChartLineType.Ray: priceToUse = TextDisplayMode == TextMode.PriceScale ? chartScale.GetValueByY(endPoint.X >= startPoint.X ? (float)FindIntersection(startPoint, endPoint, new Point(ChartPanel.W, ChartPanel.Y), new Point(ChartPanel.W, ChartPanel.H)).Y : (float)FindIntersection(startPoint, endPoint, new Point(ChartPanel.X, ChartPanel.Y), new Point(ChartPanel.X, ChartPanel.H)).Y) : EndAnchor.Price; break; default: priceToUse = priceOffScreen && TextDisplayMode == TextMode.PriceScale ? chartScale.GetValueByY(endPoint.X >= startPoint.X ? (float)FindIntersection(startPoint, endPoint, new Point(ChartPanel.W, ChartPanel.Y), new Point(ChartPanel.W, ChartPanel.H)).Y : (float)FindIntersection(startPoint, endPoint, new Point(ChartPanel.X, ChartPanel.Y), new Point(ChartPanel.X, ChartPanel.H)).Y) : EndAnchor.Price; break; } // Round the price if (LineType != ChartLineType.VerticalLine) { pricetime = priceToUse <= masterInst.RoundDownToTickSize(priceToUse) + masterInst.TickSize * 0.5 ? pricetime = masterInst.RoundDownToTickSize(priceToUse).ToString("0.00") : pricetime = masterInst.RoundToTickSize(priceToUse).ToString("0.00"); } // Check if we need to append price or time if (AppendPriceTime && DisplayText.Length > 0) { TextToDisplay = String.Format("{0} {1}", DisplayText, pricetime); } else if (AppendPriceTime) { TextToDisplay = pricetime; } // Use Label Font if one is not specified by template if (Font == null) { Font = new NinjaTrader.Gui.Tools.SimpleFont(chartControl.Properties.LabelFont.Family.ToString(), 16); } // Update DX Brushes if (offScreenDXBrushNeedsUpdate) { offScreenDXBrush.Dispose(); offScreenDXBrush = offScreenMediaBrush.ToDxBrush(RenderTarget); offScreenDXBrushNeedsUpdate = false; } if (backgroundDXBrushNeedsUpdate) { backgroundDXBrush.Dispose(); backgroundDXBrush = backgroundMediaBrush.ToDxBrush(RenderTarget); backgroundDXBrush.Opacity = (float)AreaOpacity / 100f; backgroundDXBrushNeedsUpdate = false; } // Draw TextBoxes switch (LineType) { case ChartLineType.VerticalLine: DrawTextBox(snap, TextToDisplay, extPoint.X, extPoint.Y, Stroke.BrushDX, backgroundDXBrush, OutlineStroke, 1.5708f); break; case ChartLineType.HorizontalLine: DrawTextBox(snap, TextToDisplay, extPoint.X, extPoint.Y, Stroke.BrushDX, backgroundDXBrush, OutlineStroke, 0); break; default: DrawTextBox(snap, TextToDisplay, extPoint.X, extPoint.Y, priceOffScreen && TextDisplayMode == TextMode.EndPointAtPriceScale ? offScreenDXBrush : Stroke.BrushDX, backgroundDXBrush, OutlineStroke, 0); break; } }
public override void OnRender(ChartControl chartControl, ChartScale chartScale) { if (!IsVisible) { return; } if (Anchors.All(a => a.IsEditing)) { return; } // this will be true right away to fix a restoral issue, so check if we really want to set reward if (needsRatioUpdate && DrawTarget) { SetReward(); } ChartPanel chartPanel = chartControl.ChartPanels[PanelIndex]; Point entryPoint = EntryAnchor.GetPoint(chartControl, chartPanel, chartScale); Point stopPoint = RiskAnchor.GetPoint(chartControl, chartPanel, chartScale); Point targetPoint = RewardAnchor.GetPoint(chartControl, chartPanel, chartScale); AnchorLineStroke.RenderTarget = RenderTarget; EntryLineStroke.RenderTarget = RenderTarget; StopLineStroke.RenderTarget = RenderTarget; // first of all, turn on anti-aliasing to smooth out our line RenderTarget.AntialiasMode = SharpDX.Direct2D1.AntialiasMode.PerPrimitive; RenderTarget.DrawLine(entryPoint.ToVector2(), stopPoint.ToVector2(), AnchorLineStroke.BrushDX, AnchorLineStroke.Width, AnchorLineStroke.StrokeStyle); double anchorMinX = DrawTarget ? new[] { entryPoint.X, stopPoint.X, targetPoint.X }.Min() : new[] { entryPoint.X, stopPoint.X }.Min(); double anchorMaxX = DrawTarget ? new[] { entryPoint.X, stopPoint.X, targetPoint.X }.Max() : new[] { entryPoint.X, stopPoint.X }.Max(); double lineStartX = IsExtendedLinesLeft ? chartPanel.X : anchorMinX; double lineEndX = IsExtendedLinesRight ? chartPanel.X + chartPanel.W : anchorMaxX; SharpDX.Vector2 entryStartVector = new SharpDX.Vector2((float)lineStartX, (float)entryPoint.Y); SharpDX.Vector2 entryEndVector = new SharpDX.Vector2((float)lineEndX, (float)entryPoint.Y); SharpDX.Vector2 stopStartVector = new SharpDX.Vector2((float)lineStartX, (float)stopPoint.Y); SharpDX.Vector2 stopEndVector = new SharpDX.Vector2((float)lineEndX, (float)stopPoint.Y); // don't try and draw the target stuff until we have calculated the target SharpDX.Direct2D1.Brush tmpBrush = IsInHitTest ? chartControl.SelectionBrush : AnchorLineStroke.BrushDX; if (DrawTarget) { AnchorLineStroke.RenderTarget = RenderTarget; RenderTarget.DrawLine(entryPoint.ToVector2(), targetPoint.ToVector2(), tmpBrush, AnchorLineStroke.Width, AnchorLineStroke.StrokeStyle); TargetLineStroke.RenderTarget = RenderTarget; SharpDX.Vector2 targetStartVector = new SharpDX.Vector2((float)lineStartX, (float)targetPoint.Y); SharpDX.Vector2 targetEndVector = new SharpDX.Vector2((float)lineEndX, (float)targetPoint.Y); tmpBrush = IsInHitTest ? chartControl.SelectionBrush : TargetLineStroke.BrushDX; RenderTarget.DrawLine(targetStartVector, targetEndVector, tmpBrush, TargetLineStroke.Width, TargetLineStroke.StrokeStyle); DrawPriceText(RewardAnchor, targetPoint, targetPrice, chartControl, chartPanel, chartScale); } tmpBrush = IsInHitTest ? chartControl.SelectionBrush : EntryLineStroke.BrushDX; RenderTarget.DrawLine(entryStartVector, entryEndVector, tmpBrush, EntryLineStroke.Width, EntryLineStroke.StrokeStyle); DrawPriceText(EntryAnchor, entryPoint, entryPrice, chartControl, chartPanel, chartScale); tmpBrush = IsInHitTest ? chartControl.SelectionBrush : StopLineStroke.BrushDX; RenderTarget.DrawLine(stopStartVector, stopEndVector, tmpBrush, StopLineStroke.Width, StopLineStroke.StrokeStyle); DrawPriceText(RiskAnchor, stopPoint, stopPrice, chartControl, chartPanel, chartScale); }