void DrawMessageExtendIcon(Mono.TextEditor.TextEditor editor, Cairo.Context g, double y, int errorCounterWidth, int eh) { EnsureLayoutCreated(editor); double rW = errorCounterWidth - 2; double rH = editor.LineHeight * 3 / 4; double rX = editor.Allocation.Width - rW - 2; double rY = y + (editor.LineHeight - rH) / 2; BookmarkMarker.DrawRoundRectangle(g, rX, rY, 8, rW, rH); g.Color = oldIsOver ? new Cairo.Color(0.3, 0.3, 0.3) : new Cairo.Color(0.5, 0.5, 0.5); g.Fill(); if (CollapseExtendedErrors) { if (errorCountLayout != null) { g.Color = cache.gcLight; g.Save(); g.Translate(rX + rW / 4, rY + (rH - eh) / 2); g.ShowLayout(errorCountLayout); g.Restore(); } else { g.MoveTo(rX + rW / 2 - rW / 4, rY + rH / 4); g.LineTo(rX + rW / 2 + rW / 4, rY + rH / 4); g.LineTo(rX + rW / 2, rY + rH - rH / 4); g.ClosePath(); g.Color = new Cairo.Color(1, 1, 1); g.Fill(); } } else { g.MoveTo(rX + rW / 2 - rW / 4, rY + rH - rH / 4); g.LineTo(rX + rW / 2 + rW / 4, rY + rH - rH / 4); g.LineTo(rX + rW / 2, rY + rH / 4); g.ClosePath(); g.Color = new Cairo.Color(1, 1, 1); g.Fill(); } }
protected override bool OnExposeEvent(Gdk.EventExpose evnt) { using (var cr = Gdk.CairoHelper.Create(evnt.Window)) { cr.SetSourceRGBA(1, 1, 1, 0); cr.Operator = Cairo.Operator.Source; cr.Paint(); } using (var cr = Gdk.CairoHelper.Create(evnt.Window)) { cr.Translate(width / 2, height / 2); cr.Scale(1 + scale / 8, 1 + scale / 8); int x = -(marker.ErrorTextBounds.Width) / 2; int y = -marker.ErrorTextBounds.Height / 2; if (marker.FitsInSameLine) { cr.MoveTo(x + Editor.LineHeight / 2, y); cr.LineTo(x, 0); cr.LineTo(x + Editor.LineHeight / 2, marker.ErrorTextBounds.Height / 2); } else { cr.MoveTo(x, -marker.ErrorTextBounds.Height / 2); cr.LineTo(x, marker.ErrorTextBounds.Height / 2); } cr.LineTo(x + marker.ErrorTextBounds.Width, marker.ErrorTextBounds.Height / 2); cr.LineTo(x + marker.ErrorTextBounds.Width, y); cr.ClosePath(); Mono.TextEditor.HslColor hsl = marker.colorMatrix [0, 0, 0, 0, 0]; double delta = 1 + 2 - scale; hsl.S += delta; var color = (Cairo.Color)hsl; color.A = opacity; cr.Color = color; cr.FillPreserve(); color = marker.colorMatrix [0, 0, 2, 0, 0]; color.A = opacity; cr.Color = color; cr.Stroke(); int errorCounterWidth = 0; if (marker.Errors.Count > 1) { double rY = y + Editor.LineHeight / 6; int ew, eh; marker.errorCountLayout.GetPixelSize(out ew, out eh); errorCounterWidth = ew + 10; int rX = x + marker.ErrorTextBounds.Width - errorCounterWidth; int rW = errorCounterWidth - 2; double rH = Editor.LineHeight * 3 / 4; BookmarkMarker.DrawRoundRectangle(cr, rX, rY, 8, rW, rH); cr.Color = new Cairo.Color(0.5, 0.5, 0.5); cr.Fill(); cr.MoveTo(rX + rW / 2 - rW / 4, rY + rH - rH / 4); cr.LineTo(rX + rW / 2 + rW / 4, rY + rH - rH / 4); cr.LineTo(rX + rW / 2, rY + rH / 4); cr.ClosePath(); cr.Color = new Cairo.Color(1, 1, 1); cr.Fill(); } cr.Color = new Cairo.Color(0, 0, 0); marker.EnsureLayoutCreated(base.Editor); int layoutWidth, layoutHeight; marker.Layouts [0].Layout.GetPixelSize(out layoutWidth, out layoutHeight); double ly; if (marker.CollapseExtendedErrors || marker.Errors.Count == 1) { ly = 1 + y + (marker.ErrorTextBounds.Height - layoutHeight) / 2; double x2 = x + MessageBubbleTextMarker.border; if (marker.FitsInSameLine) { x2 += 1 + Editor.LineHeight / 2; } cr.Translate(x2, ly); cr.ShowLayout(marker.Layouts [0].Layout); } else { ly = 1 + y + (Editor.LineHeight - layoutHeight) / 2; for (int i = 0; i < marker.Errors.Count; i++) { marker.Layouts [i].Layout.GetPixelSize(out layoutWidth, out layoutHeight); cr.Save(); double x2; if (i == 0) { x2 = x + marker.ErrorTextBounds.Width - layoutWidth - errorCounterWidth; } else { x2 = x + MessageBubbleTextMarker.border; } if (marker.FitsInSameLine) { x2 += Editor.LineHeight / 2; } cr.Translate(x2, ly); cr.ShowLayout(marker.Layouts [i].Layout); cr.Restore(); ly += Editor.LineHeight; } } } return(false); }
public bool DrawBackground(TextEditor editor, Cairo.Context g, TextViewMargin.LayoutWrapper layout2, int selectionStart, int selectionEnd, int startOffset, int endOffset, double y, double startXPos, double endXPos, ref bool drawBg) { if (!IsVisible || DebuggingService.IsDebugging) { return(true); } EnsureLayoutCreated(editor); double x = editor.TextViewMargin.XOffset; int right = editor.Allocation.Width; int errorCounterWidth = 0; bool isCaretInLine = startOffset <= editor.Caret.Offset && editor.Caret.Offset <= endOffset; int ew = 0, eh = 0; if (errors.Count > 1 && errorCountLayout != null) { errorCountLayout.GetPixelSize(out ew, out eh); errorCounterWidth = ew + 10; } double x2 = System.Math.Max(right - LayoutWidth - border - (ShowIconsInBubble ? errorPixbuf.Width : 0) - errorCounterWidth, fitsInSameLine ? editor.TextViewMargin.XOffset + editor.LineHeight / 2 : editor.TextViewMargin.XOffset); bool isEolSelected = editor.IsSomethingSelected && editor.SelectionMode != SelectionMode.Block ? editor.SelectionRange.Contains(lineSegment.Offset + lineSegment.EditableLength) : false; int active = editor.Document.GetTextAt(lineSegment) == initialText ? 0 : 1; int highlighted = active == 0 && isCaretInLine ? 1 : 0; int selected = 0; double topSize = Math.Floor(editor.LineHeight / 2); double bottomSize = editor.LineHeight / 2 + editor.LineHeight % 2; if (!fitsInSameLine) { if (isEolSelected) { x -= (int)editor.HAdjustment.Value; editor.TextViewMargin.DrawRectangleWithRuler(g, x, new Cairo.Rectangle(x, y + editor.LineHeight, editor.TextViewMargin.TextStartPosition, editor.LineHeight), editor.ColorStyle.Default.CairoBackgroundColor, true); editor.TextViewMargin.DrawRectangleWithRuler(g, x + editor.TextViewMargin.TextStartPosition, new Cairo.Rectangle(x + editor.TextViewMargin.TextStartPosition, y + editor.LineHeight, editor.Allocation.Width + (int)editor.HAdjustment.Value, editor.LineHeight), editor.ColorStyle.Selection.CairoBackgroundColor, true); x += (int)editor.HAdjustment.Value; } else { editor.TextViewMargin.DrawRectangleWithRuler(g, x, new Cairo.Rectangle(x, y + editor.LineHeight, x2, editor.LineHeight), editor.ColorStyle.Default.CairoBackgroundColor, true); } } DrawRectangle(g, x, y, right, topSize); g.Color = colorMatrix [active, TOP, LIGHT, highlighted, selected]; g.Fill(); DrawRectangle(g, x, y + topSize, right, bottomSize); g.Color = colorMatrix [active, BOTTOM, LIGHT, highlighted, selected]; g.Fill(); g.MoveTo(new Cairo.PointD(x, y + 0.5)); g.LineTo(new Cairo.PointD(x + right, y + 0.5)); g.Color = colorMatrix [active, TOP, LINE, highlighted, selected]; g.Stroke(); g.MoveTo(new Cairo.PointD(x, y + editor.LineHeight - 0.5)); g.LineTo(new Cairo.PointD((fitsInSameLine ? x + right : x2 + 1), y + editor.LineHeight - 0.5)); g.Color = colorMatrix [active, BOTTOM, LINE, highlighted, selected]; g.Stroke(); if (editor.Options.ShowRuler) { double divider = Math.Max(editor.TextViewMargin.XOffset, x + editor.TextViewMargin.RulerX); g.MoveTo(new Cairo.PointD(divider + 0.5, y)); g.LineTo(new Cairo.PointD(divider + 0.5, y + editor.LineHeight)); g.Color = colorMatrix [active, BOTTOM, LINE, highlighted, selected]; g.Stroke(); } // draw background if (layout2.StartSet || selectionStart == endOffset) { double startX; double endX; if (selectionStart != endOffset) { var start = layout2.Layout.IndexToPos((int)layout2.SelectionStartIndex); startX = (int)(start.X / Pango.Scale.PangoScale); var end = layout2.Layout.IndexToPos((int)layout2.SelectionEndIndex); endX = (int)(end.X / Pango.Scale.PangoScale); } else { startX = x2; endX = startX; } if (editor.MainSelection.SelectionMode == SelectionMode.Block && startX == endX) { endX = startX + 2; } startX += startXPos; endX += startXPos; startX = Math.Max(editor.TextViewMargin.XOffset, startX); // clip region to textviewmargin start if (isEolSelected) { endX = editor.Allocation.Width + (int)editor.HAdjustment.Value; } if (startX < endX) { DrawRectangle(g, startX, y, endX - startX, topSize); g.Color = colorMatrix [active, TOP, LIGHT, highlighted, 1]; g.Fill(); DrawRectangle(g, startX, y + topSize, endX - startX, bottomSize); g.Color = colorMatrix [active, BOTTOM, LIGHT, highlighted, 1]; g.Fill(); g.MoveTo(new Cairo.PointD(startX, y + 0.5)); g.LineTo(new Cairo.PointD(endX, y + 0.5)); g.Color = colorMatrix [active, TOP, LINE, highlighted, 1]; g.Stroke(); if (startX < x2) { g.MoveTo(new Cairo.PointD(startX, y + editor.LineHeight - 0.5)); g.LineTo(new Cairo.PointD(System.Math.Min(endX, x2 + 1), y + editor.LineHeight - 0.5)); g.Color = colorMatrix [active, BOTTOM, LINE, highlighted, 1]; g.Stroke(); if (x2 + 1 < endX) { g.MoveTo(new Cairo.PointD(x2 + 1, y + editor.LineHeight - 0.5)); g.LineTo(new Cairo.PointD(endX, y + editor.LineHeight - 0.5)); g.Color = colorMatrix [active, BOTTOM, LIGHT, highlighted, 1]; g.Stroke(); } } if (editor.Options.ShowRuler) { double divider = Math.Max(editor.TextViewMargin.XOffset, x + editor.TextViewMargin.RulerX); g.MoveTo(new Cairo.PointD(divider + 0.5, y)); g.LineTo(new Cairo.PointD(divider + 0.5, y + editor.LineHeight)); g.Color = colorMatrix [active, BOTTOM, LINE, highlighted, 1]; g.Stroke(); } } } if (!fitsInSameLine) { y += editor.LineHeight; } double y2 = y + 0.5; double y2Bottom = y2 + editor.LineHeight - 1; selected = isEolSelected && (CollapseExtendedErrors || errors.Count == 1) ? 1 : 0; // draw message text background if (CollapseExtendedErrors || errors.Count == 1) { if (!fitsInSameLine) { // draw box below line g.MoveTo(new Cairo.PointD(x2 + 0.5, y2 - 1)); g.LineTo(new Cairo.PointD(x2 + 0.5, y2Bottom)); g.LineTo(new Cairo.PointD(right, y2Bottom)); g.LineTo(new Cairo.PointD(right, y2 - 1)); g.ClosePath(); g.Color = colorMatrix [active, BOTTOM, LIGHT, highlighted, selected]; g.Fill(); g.MoveTo(new Cairo.PointD(x2 + 0.5, y2 - 1)); g.LineTo(new Cairo.PointD(x2 + 0.5, y2Bottom)); g.LineTo(new Cairo.PointD(right, y2Bottom)); g.Color = colorMatrix [active, BOTTOM, LINE, highlighted, selected]; g.Stroke(); } else { // draw 'arrow marker' in the same line g.MoveTo(new Cairo.PointD(x2 + 0.5, y2)); double mid = y2 + topSize; g.LineTo(new Cairo.PointD(x2 - editor.LineHeight / 2 + 0.5, mid)); g.LineTo(new Cairo.PointD(right, mid)); g.LineTo(new Cairo.PointD(right, y2)); g.ClosePath(); g.Color = colorMatrix [active, TOP, DARK, highlighted, selected]; g.Fill(); g.MoveTo(new Cairo.PointD(x2 + 0.5, y2Bottom)); g.LineTo(new Cairo.PointD(x2 - editor.LineHeight / 2 + 0.5, mid)); g.LineTo(new Cairo.PointD(right, mid)); g.LineTo(new Cairo.PointD(right, y2Bottom)); g.ClosePath(); g.Color = colorMatrix [active, BOTTOM, DARK, highlighted, selected]; g.Fill(); // draw border g.MoveTo(new Cairo.PointD(x2 + 0.5, y2)); g.LineTo(new Cairo.PointD(x2 - editor.LineHeight / 2 + 0.5, y2 + editor.LineHeight / 2)); g.LineTo(new Cairo.PointD(x2 + 0.5, y2Bottom)); g.LineTo(new Cairo.PointD(right, y2Bottom)); g.LineTo(new Cairo.PointD(right, y2)); g.ClosePath(); g.Color = colorMatrix [active, BOTTOM, LINE, highlighted, selected]; g.Stroke(); } } else { if (!fitsInSameLine) { // draw box below line g.MoveTo(new Cairo.PointD(x2 + 0.5, y2 - 1)); g.LineTo(new Cairo.PointD(x2 + 0.5, y2Bottom)); g.LineTo(new Cairo.PointD(right, y2Bottom)); g.LineTo(new Cairo.PointD(right, y2 - 1)); g.ClosePath(); } else { // draw filled arrow box g.MoveTo(new Cairo.PointD(x2 + 0.5, y2)); g.LineTo(new Cairo.PointD(x2 - editor.LineHeight / 2 + 0.5, y2 + editor.LineHeight / 2)); g.LineTo(new Cairo.PointD(x2 + 0.5, y2Bottom)); g.LineTo(new Cairo.PointD(right, y2Bottom)); g.LineTo(new Cairo.PointD(right, y2)); g.ClosePath(); } g.Color = colorMatrix [active, BOTTOM, LIGHT, highlighted, selected]; g.Fill(); // draw light bottom line g.MoveTo(new Cairo.PointD(right, y2Bottom)); g.LineTo(new Cairo.PointD(x2 + 0.5, y2Bottom)); g.Stroke(); // stroke left line if (fitsInSameLine) { g.MoveTo(new Cairo.PointD(x2 + 0.5, y2)); g.LineTo(new Cairo.PointD(x2 - editor.LineHeight / 2 + 0.5, y2 + editor.LineHeight / 2)); g.LineTo(new Cairo.PointD(x2 + 0.5, y2Bottom)); } else { g.MoveTo(new Cairo.PointD(x2 + 0.5, y2 - 1)); g.LineTo(new Cairo.PointD(x2 + 0.5, y2Bottom + 1)); } g.Color = colorMatrix [active, BOTTOM, LINE, highlighted, selected]; g.Stroke(); // stroke top line if (fitsInSameLine) { g.Color = colorMatrix [active, BOTTOM, LINE, highlighted, selected]; g.MoveTo(new Cairo.PointD(right, y2)); g.LineTo(new Cairo.PointD(x2 + 0.5, y2)); g.Stroke(); } } if (editor.Options.ShowRuler) { double divider = Math.Max(editor.TextViewMargin.XOffset, x + editor.TextViewMargin.RulerX); if (divider >= x2) { g.MoveTo(new Cairo.PointD(divider + 0.5, y2)); g.LineTo(new Cairo.PointD(divider + 0.5, y2Bottom)); g.Color = colorMatrix [active, BOTTOM, DARK, highlighted, selected]; g.Stroke(); } } if (errors.Count > 1 && errorCountLayout != null) { double rX = x2 + (ShowIconsInBubble ? errorPixbuf.Width : 0) + border + LayoutWidth; double rY = y + editor.LineHeight / 6; double rW = errorCounterWidth - 2; double rH = editor.LineHeight * 3 / 4; BookmarkMarker.DrawRoundRectangle(g, rX, rY, 8, rW, rH); g.Color = oldIsOver ? new Cairo.Color(0.3, 0.3, 0.3) : new Cairo.Color(0.5, 0.5, 0.5); g.Fill(); if (CollapseExtendedErrors) { g.Color = gcLight; g.Save(); g.Translate(x2 + (ShowIconsInBubble ? errorPixbuf.Width : 0) + border + LayoutWidth + 4, y + (editor.LineHeight - eh) / 2 + eh % 2); g.ShowLayout(errorCountLayout); g.Restore(); } else { g.MoveTo(rX + rW / 2 - rW / 4, rY + rH - rH / 4); g.LineTo(rX + rW / 2 + rW / 4, rY + rH - rH / 4); g.LineTo(rX + rW / 2, rY + rH / 4); g.ClosePath(); g.Color = new Cairo.Color(1, 1, 1); g.Fill(); } } for (int i = 0; i < layouts.Count; i++) { LayoutDescriptor layout = layouts [i]; x2 = right - layout.Width - border - errorPixbuf.Width; if (i == 0) { x2 -= errorCounterWidth; } x2 = System.Math.Max(x2, fitsInSameLine ? editor.TextViewMargin.XOffset + editor.LineHeight / 2 : editor.TextViewMargin.XOffset); if (i > 0) { editor.TextViewMargin.DrawRectangleWithRuler(g, x, new Cairo.Rectangle(x, y, right, editor.LineHeight), isEolSelected ? editor.ColorStyle.Selection.CairoBackgroundColor : editor.ColorStyle.Default.CairoBackgroundColor, true); g.MoveTo(new Cairo.PointD(x2 + 0.5, y)); g.LineTo(new Cairo.PointD(x2 + 0.5, y + editor.LineHeight)); g.LineTo(new Cairo.PointD(right, y + editor.LineHeight)); g.LineTo(new Cairo.PointD(right, y)); g.ClosePath(); if (CollapseExtendedErrors) { using (var pat = new Cairo.LinearGradient(x2, y, x2, y + editor.LineHeight)) { pat.AddColorStop(0, colorMatrix [active, TOP, LIGHT, highlighted, selected]); pat.AddColorStop(1, colorMatrix [active, BOTTOM, LIGHT, highlighted, selected]); g.Pattern = pat; } } else { g.Color = colorMatrix[active, TOP, LIGHT, highlighted, selected]; } g.Fill(); if (editor.Options.ShowRuler) { double divider = Math.Max(editor.TextViewMargin.XOffset, x + editor.TextViewMargin.RulerX); if (divider >= x2) { g.MoveTo(new Cairo.PointD(divider + 0.5, y)); g.LineTo(new Cairo.PointD(divider + 0.5, y + editor.LineHeight)); g.Color = colorMatrix[active, BOTTOM, DARK, highlighted, selected]; g.Stroke(); } } } int lw, lh; layout.Layout.GetPixelSize(out lw, out lh); g.Color = (HslColor)(selected == 0 ? gc : gcSelected); g.Save(); g.Translate(x2 + errorPixbuf.Width + border, y + (editor.LineHeight - layout.Height) / 2 + layout.Height % 2); g.ShowLayout(layout.Layout); g.Restore(); y += editor.LineHeight; if (!UseVirtualLines) { break; } } return(true); }