protected override bool OnExposeEvent(Gdk.EventExpose evnt) { bool idle = incoming_track == null && current_track == null; if (!Visible || !IsMapped || (idle && !CanRenderIdle)) { return(true); } Cairo.Context cr = Gdk.CairoHelper.Create(evnt.Window); foreach (Gdk.Rectangle damage in evnt.Region.GetRectangles()) { cr.Rectangle(damage.X, damage.Y, damage.Width, damage.Height); cr.Clip(); if (idle) { RenderIdle(cr); } else { RenderAnimation(cr); } cr.ResetClip(); } CairoExtensions.DisposeContext(cr); return(true); }
public static void RenderTiled(this Cairo.Context self, Gdk.Pixbuf source, Gdk.Rectangle area, Gdk.Rectangle clip, double opacity = 1) { Gdk.CairoHelper.SetSourcePixbuf(self, source, area.X, area.Y); cairo_pattern_set_extend(self.Pattern.Pointer, CairoExtend.CAIRO_EXTEND_REPEAT); self.Rectangle(clip.ToCairoRect()); self.Clip(); self.PaintWithAlpha(opacity); self.ResetClip(); }
void DrawBuildEffect(Cairo.Context context, Gdk.Rectangle area, double progress, double opacity) { context.Save(); LayoutRoundedRectangle(context, area); context.Clip(); Gdk.Point center = new Gdk.Point(area.Left + 19, (area.Top + area.Bottom) / 2); context.Translate(center.X, center.Y); var circles = new [] { new { Radius = 200, Thickness = 12, Speed = 1, ArcLength = Math.PI * 1.50 }, new { Radius = 195, Thickness = 15, Speed = 2, ArcLength = Math.PI * 0.50 }, new { Radius = 160, Thickness = 17, Speed = 3, ArcLength = Math.PI * 0.75 }, new { Radius = 200, Thickness = 15, Speed = 2, ArcLength = Math.PI * 0.25 }, new { Radius = 240, Thickness = 12, Speed = 3, ArcLength = Math.PI * 1.50 }, new { Radius = 160, Thickness = 17, Speed = 3, ArcLength = Math.PI * 0.75 }, new { Radius = 200, Thickness = 15, Speed = 2, ArcLength = Math.PI * 0.25 }, new { Radius = 215, Thickness = 20, Speed = 2, ArcLength = Math.PI * 1.25 } }; double zmod = 1.0d; double zporg = progress; foreach (var arc in circles) { double zoom = 1.0d; zoom = (double)Math.Sin(zporg * Math.PI * 2 + zmod); zoom = ((zoom + 1) / 6.0d) + .05d; context.Rotate(Math.PI * 2 * progress * arc.Speed); context.MoveTo(arc.Radius * zoom, 0); context.Arc(0, 0, arc.Radius * zoom, 0, arc.ArcLength); context.LineWidth = arc.Thickness * zoom; context.SetSourceColor(CairoExtensions.ParseColor("B1DDED", 0.35 * opacity)); context.Stroke(); context.Rotate(Math.PI * 2 * -progress * arc.Speed); progress = -progress; context.Rotate(Math.PI * 2 * progress * arc.Speed); context.MoveTo(arc.Radius * zoom, 0); context.Arc(0, 0, arc.Radius * zoom, 0, arc.ArcLength); context.LineWidth = arc.Thickness * zoom; context.Stroke(); context.Rotate(Math.PI * 2 * -progress * arc.Speed); progress = -progress; zmod += (float)Math.PI / circles.Length; } context.LineWidth = 1; context.ResetClip(); context.Restore(); }
public static void RenderTiled(this Cairo.Context self, Gdk.Pixbuf source, Gdk.Rectangle area, Gdk.Rectangle clip, double opacity = 1) { Gdk.CairoHelper.SetSourcePixbuf(self, source, area.X, area.Y); //NOTE: Mono.Cairo.Context.Pattern returns an object than cannot be safely disposed, so P/Invoke directly var pattern = cairo_get_source(self.Handle); cairo_pattern_set_extend(pattern, CairoExtend.CAIRO_EXTEND_REPEAT); self.Rectangle(clip.ToCairoRect()); self.Clip(); self.PaintWithAlpha(opacity); self.ResetClip(); }
protected virtual void DrawBackground(Cairo.Context context, Gdk.Rectangle region) { LayoutRoundedRectangle(context, region); context.ClipPreserve(); using (LinearGradient lg = new LinearGradient(region.X, region.Y, region.X, region.Y + region.Height)) { lg.AddColorStop(0, Styles.StatusBarFill1Color); lg.AddColorStop(1, Styles.StatusBarFill4Color); context.SetSource(lg); context.FillPreserve(); } context.Save(); double midX = region.X + region.Width / 2.0; double midY = region.Y + region.Height; context.Translate(midX, midY); using (RadialGradient rg = new RadialGradient(0, 0, 0, 0, 0, region.Height * 1.2)) { rg.AddColorStop(0, Styles.StatusBarFill1Color); rg.AddColorStop(1, Styles.WithAlpha(Styles.StatusBarFill1Color, 0)); context.Scale(region.Width / (double)region.Height, 1.0); context.SetSource(rg); context.Fill(); } context.Restore(); using (LinearGradient lg = new LinearGradient(0, region.Y, 0, region.Y + region.Height)) { lg.AddColorStop(0, Styles.StatusBarShadowColor1); lg.AddColorStop(1, Styles.WithAlpha(Styles.StatusBarShadowColor1, Styles.StatusBarShadowColor1.A * 0.2)); LayoutRoundedRectangle(context, region, 0, -1); context.LineWidth = 1; context.SetSource(lg); context.Stroke(); } using (LinearGradient lg = new LinearGradient(0, region.Y, 0, region.Y + region.Height)) { lg.AddColorStop(0, Styles.StatusBarShadowColor2); lg.AddColorStop(1, Styles.WithAlpha(Styles.StatusBarShadowColor2, Styles.StatusBarShadowColor2.A * 0.2)); LayoutRoundedRectangle(context, region, 0, -2); context.LineWidth = 1; context.SetSource(lg); context.Stroke(); } context.ResetClip(); }
protected override void DrawBackground (Context context, Gdk.Rectangle region) { LayoutRoundedRectangle (context, region); context.Clip (); context.SetSourceColor (CairoExtensions.ParseColor ("D3E6FF")); context.Paint (); context.Save (); context.Translate (region.X + region.Width / 2.0, region.Y + region.Height); using (var rg = new RadialGradient (0, 0, 0, 0, 0, region.Height * 1.2)) { var color = CairoExtensions.ParseColor ("E5F0FF"); rg.AddColorStop (0, color); color.A = 0; rg.AddColorStop (1, color); context.Scale (region.Width / (double)region.Height, 1.0); context.SetSource (rg); context.Paint (); } context.Restore (); LayoutRoundedRectangle (context, region, -3, -3, 2); context.SetSourceRGBA (1, 1, 1, 0.4); context.LineWidth = 1; context.StrokePreserve (); context.Clip (); int boxSize = 11; int x = region.Left + (region.Width % boxSize) / 2; for (; x < region.Right; x += boxSize) { context.MoveTo (x + 0.5, region.Top); context.LineTo (x + 0.5, region.Bottom); } int y = region.Top + (region.Height % boxSize) / 2; y += boxSize / 2; for (; y < region.Bottom; y += boxSize) { context.MoveTo (region.Left, y + 0.5); context.LineTo (region.Right, y + 0.5); } context.SetSourceRGBA (1, 1, 1, 0.2); context.Stroke (); context.ResetClip (); }
void DrawProgressBar(Cairo.Context context, double progress, Gdk.Rectangle bounding, StatusArea.RenderArg arg) { LayoutRoundedRectangle(context, new Gdk.Rectangle(bounding.X, bounding.Y, (int)(bounding.Width * progress), bounding.Height), 0, 0, 1); context.Clip(); LayoutRoundedRectangle(context, bounding, 0, 0, 1); context.SetSourceColor(Styles.WithAlpha(Styles.StatusBarProgressBackgroundColor, Styles.StatusBarProgressBackgroundColor.A * arg.ProgressBarAlpha)); context.FillPreserve(); context.ResetClip(); context.SetSourceColor(Styles.WithAlpha(Styles.StatusBarProgressOutlineColor, Styles.StatusBarProgressOutlineColor.A * arg.ProgressBarAlpha)); context.LineWidth = 1; context.Stroke(); }
private static void Draw(LayoutGroup group, Cairo.Context context, bool needClip) { if (needClip) { var rect = group.Rect; var style = group.Style; context.Rectangle(rect.X + style.PaddingLeft + style.BorderLeft, rect.Y + style.PaddingTop + style.BorderTop, rect.Width - style.PaddingHorizontal - style.BorderHorizontal, rect.Height - style.PaddingVertical - style.BorderVertical); //context.StrokePreserve(); context.Clip(); } foreach (var entry in @group.Entries) { if (entry.HorizontallyStretched || entry.VerticallyStretched) { context.FillRectangle(entry.Rect, CairoEx.ColorLightBlue); } else if (entry.IsFixedWidth || entry.IsFixedHeight) { context.FillRectangle(entry.Rect, CairoEx.ColorOrange); } else { context.FillRectangle(entry.Rect, CairoEx.ColorPink); } context.StrokeRectangle(entry.Rect, CairoEx.ColorBlack); var innerGroup = entry as LayoutGroup; if (innerGroup != null) { context.Save(); Draw(innerGroup, context, needClip); context.Restore(); } } if (needClip) { context.ResetClip(); } }
void DrawErrorAnimation(Cairo.Context context, StatusArea.RenderArg arg) { const int surfaceWidth = 2000; double opacity; int progress; if (arg.ErrorAnimationProgress < .5f) { progress = (int)(arg.ErrorAnimationProgress * arg.Allocation.Width * 2.4); opacity = 1.0d; } else { progress = (int)(arg.ErrorAnimationProgress * arg.Allocation.Width * 2.4); opacity = 1.0d - (arg.ErrorAnimationProgress - .5d) * 2; } LayoutRoundedRectangle(context, arg.Allocation); context.Clip(); context.CachedDraw(surface: ref errorSurface, position: new Gdk.Point(arg.Allocation.X - surfaceWidth + progress, arg.Allocation.Y), size: new Gdk.Size(surfaceWidth, arg.Allocation.Height), opacity: (float)opacity, draw: (c, o) => { // The smaller the pixel range of our gradient the less error there will be in it. using (var lg = new LinearGradient(surfaceWidth - 250, 0, surfaceWidth, 0)) { lg.AddColorStop(0.00, Styles.WithAlpha(Styles.StatusBarErrorColor, 0.15 * o)); lg.AddColorStop(0.10, Styles.WithAlpha(Styles.StatusBarErrorColor, 0.15 * o)); lg.AddColorStop(0.88, Styles.WithAlpha(Styles.StatusBarErrorColor, 0.30 * o)); lg.AddColorStop(1.00, Styles.WithAlpha(Styles.StatusBarErrorColor, 0.00 * o)); c.SetSource(lg); c.Paint(); } }); context.ResetClip(); }
void Draw (Context ctx) { int tabArea = tabEndX - tabStartX; int x = GetRenderOffset (); const int y = 0; int n = 0; Action<Context> drawActive = c => { }; var drawCommands = new List<Action<Context>> (); for (; n < notebook.Tabs.Count; n++) { if (x + TabWidth < tabStartX) { x += TabWidth; continue; } if (x > tabEndX) break; int closingWidth; var cmd = DrawClosingTab (n, new Gdk.Rectangle (x, y, 0, Allocation.Height), out closingWidth); drawCommands.Add (cmd); x += closingWidth; var tab = (DockNotebookTab)notebook.Tabs [n]; bool active = tab == notebook.CurrentTab; int width = Math.Min (TabWidth, Math.Max (50, tabEndX - x - 1)); if (tab == notebook.Tabs.Last ()) width += LastTabWidthAdjustment; width = (int)(width * tab.WidthModifier); if (active) { int tmp = x; drawActive = c => DrawTab (c, tab, Allocation, new Gdk.Rectangle (tmp, y, width, Allocation.Height), true, true, draggingTab, CreateTabLayout (tab)); tab.Allocation = new Gdk.Rectangle (tmp, Allocation.Y, width, Allocation.Height); } else { int tmp = x; bool highlighted = tab == highlightedTab; if (tab.SaveStrength > 0.0f) { tmp = (int)(tab.SavedAllocation.X + (tmp - tab.SavedAllocation.X) * (1.0f - tab.SaveStrength)); } drawCommands.Add (c => DrawTab (c, tab, Allocation, new Gdk.Rectangle (tmp, y, width, Allocation.Height), highlighted, false, false, CreateTabLayout (tab))); tab.Allocation = new Gdk.Rectangle (tmp, Allocation.Y, width, Allocation.Height); } x += width; } var allocation = Allocation; int tabWidth; drawCommands.Add (DrawClosingTab (n, new Gdk.Rectangle (x, y, 0, allocation.Height), out tabWidth)); drawCommands.Reverse (); DrawBackground (ctx, allocation); // Draw breadcrumb bar header if (notebook.Tabs.Count > 0) { ctx.Rectangle (0, allocation.Height - BottomBarPadding, allocation.Width, BottomBarPadding); ctx.SetSourceColor (Styles.BreadcrumbBackgroundColor); ctx.Fill (); } ctx.Rectangle (tabStartX - LeanWidth / 2, allocation.Y, tabArea + LeanWidth, allocation.Height); ctx.Clip (); foreach (var cmd in drawCommands) cmd (ctx); ctx.ResetClip (); // Redraw the dragging tab here to be sure its on top. We drew it before to get the sizing correct, this should be fixed. drawActive (ctx); }
public void Render(Cairo.Context context, StatusArea.RenderArg arg, Gtk.Widget widget) { context.CachedDraw(surface: ref backgroundSurface, region: arg.Allocation, draw: (c, o) => DrawBackground(c, new Gdk.Rectangle(0, 0, arg.Allocation.Width, arg.Allocation.Height))); if (arg.BuildAnimationOpacity > 0.001f) { DrawBuildEffect(context, arg.Allocation, arg.BuildAnimationProgress, arg.BuildAnimationOpacity); } if (arg.ErrorAnimationProgress > 0.001 && arg.ErrorAnimationProgress < .999) { DrawErrorAnimation(context, arg); } DrawBorder(context, arg.Allocation); if (arg.HoverProgress > 0.001f) { context.Clip(); int x1 = arg.Allocation.X + arg.MousePosition.X - 200; int x2 = x1 + 400; using (Cairo.LinearGradient gradient = new LinearGradient(x1, 0, x2, 0)) { Cairo.Color targetColor = Styles.StatusBarFill1Color; Cairo.Color transparentColor = targetColor; targetColor.A = .7; transparentColor.A = 0; targetColor.A = .7 * arg.HoverProgress; gradient.AddColorStop(0.0, transparentColor); gradient.AddColorStop(0.5, targetColor); gradient.AddColorStop(1.0, transparentColor); context.SetSource(gradient); context.Rectangle(x1, arg.Allocation.Y, x2 - x1, arg.Allocation.Height); context.Fill(); } context.ResetClip(); } else { context.NewPath(); } int progress_bar_x = arg.ChildAllocation.X; int progress_bar_width = arg.ChildAllocation.Width; if (arg.CurrentPixbuf != null) { int y = arg.Allocation.Y + (arg.Allocation.Height - (int)arg.CurrentPixbuf.Size.Height) / 2; context.DrawImage(widget, arg.CurrentPixbuf, arg.ChildAllocation.X, y); progress_bar_x += (int)arg.CurrentPixbuf.Width + Styles.ProgressBarOuterPadding; progress_bar_width -= (int)arg.CurrentPixbuf.Width + Styles.ProgressBarOuterPadding; } int center = arg.Allocation.Y + arg.Allocation.Height / 2; Gdk.Rectangle progressArea = new Gdk.Rectangle(progress_bar_x, center - Styles.ProgressBarHeight / 2, progress_bar_width, Styles.ProgressBarHeight); if (arg.ShowProgressBar || arg.ProgressBarAlpha > 0) { DrawProgressBar(context, arg.ProgressBarFraction, progressArea, arg); ClipProgressBar(context, progressArea); } int text_x = progress_bar_x + Styles.ProgressBarInnerPadding; int text_width = progress_bar_width - (Styles.ProgressBarInnerPadding * 2); double textTweenValue = arg.TextAnimationProgress; if (arg.LastText != null) { double opacity = Math.Max(0.0f, 1.0f - textTweenValue); DrawString(arg.LastText, arg.LastTextIsMarkup, context, text_x, center - (int)(textTweenValue * arg.Allocation.Height * 0.3), text_width, opacity, arg.Pango, arg); } if (arg.CurrentText != null) { DrawString(arg.CurrentText, arg.CurrentTextIsMarkup, context, text_x, center + (int)((1.0f - textTweenValue) * arg.Allocation.Height * 0.3), text_width, Math.Min(textTweenValue, 1.0), arg.Pango, arg); } if (arg.ShowProgressBar || arg.ProgressBarAlpha > 0) { context.ResetClip(); } }
protected override void onDraw(Cairo.Context gr) { if (datas == null) { return; } lock (mutex) { gr.SelectFontFace(Font.Name, Font.Slant, Font.Wheight); gr.SetFontSize(Font.Size); Crow.Rectangle scrBar = ClientRectangle; if (datas?.Count > visibleLines) { scrBar.X += ClientRectangle.Width - scrBarWidth; scrBar.Width = scrBarWidth; } Crow.Rectangle r = ClientRectangle; r.Width -= scrBarWidth; int diffScroll = lastScroll - scroll; int diffVisible = visibleLines - lastVisibleLines; int limInf = 0; int limSup = diffScroll + diffVisible; if (diffScroll < 0) { limInf = lastVisibleLines + diffScroll; limSup = visibleLines; } gr.Save(); gr.ResetClip(); gr.Rectangle(r.X, r.Y + limInf * fe.Height, r.Width, (limSup - limInf) * fe.Height); if (lastHoverIndex != HoverIndex) { if (lastHoverIndex >= 0) { gr.Rectangle(r.X, r.Y + (lastHoverIndex - Scroll) * fe.Height, r.Width, fe.Height); } if (HoverIndex >= 0) { gr.Rectangle(r.X, r.Y + (HoverIndex - Scroll) * fe.Height, r.Width, fe.Height); } } if (lastSelectedIndex != SelectedIndex) { if (lastSelectedIndex >= 0) { gr.Rectangle(r.X, r.Y + (lastSelectedIndex - Scroll) * fe.Height, r.Width, fe.Height); } if (selectedIndex >= 0) { gr.Rectangle(r.X, r.Y + (SelectedIndex - Scroll) * fe.Height, r.Width, fe.Height); } } if (datas?.Count > visibleLines && diffScroll != 0) { gr.Rectangle(scrBar); } gr.ClipPreserve(); gr.Operator = Operator.Clear; gr.Fill(); gr.Operator = Operator.Over; base.onDraw(gr); Foreground.SetAsSource(gr); int i = limInf; while (i < limSup) { if (i + Scroll >= Datas.Count) { break; } drawDataLine(gr, i + Scroll, r.X, r.Y + i * fe.Height, (double)r.Width, fe.Height); i++; } int redrawnLines = limSup - limInf; System.Diagnostics.Debug.WriteLine("draw {0} lines from {1} to {2}", redrawnLines, limInf, limSup - 1); if (lastHoverIndex != HoverIndex) { if (lastHoverIndex >= 0 && (redrawnLines == 0 || (lastHoverIndex < limInf + Scroll || lastHoverIndex >= limSup + Scroll))) { drawDataLine(gr, lastHoverIndex, r.X, r.Y + (lastHoverIndex - Scroll) * fe.Height, (double)r.Width, fe.Height); } if (HoverIndex >= 0 && (redrawnLines == 0 || (HoverIndex < limInf + Scroll || HoverIndex >= limSup + Scroll))) { drawDataLine(gr, HoverIndex, r.X, r.Y + (HoverIndex - Scroll) * fe.Height, (double)r.Width, fe.Height); } } if (lastSelectedIndex != SelectedIndex) { if (lastSelectedIndex >= 0 && (redrawnLines == 0 || (lastSelectedIndex < limInf + Scroll || lastSelectedIndex >= limSup + Scroll))) { drawDataLine(gr, lastSelectedIndex, r.X, r.Y + (lastSelectedIndex - Scroll) * fe.Height, (double)r.Width, fe.Height); } if (SelectedIndex >= 0 && (redrawnLines == 0 || (SelectedIndex < limInf + Scroll || SelectedIndex >= limSup + Scroll))) { drawDataLine(gr, SelectedIndex, r.X, r.Y + (SelectedIndex - Scroll) * fe.Height, (double)r.Width, fe.Height); } } double x = ClientRectangle.X; gr.LineWidth = 1; for (i = 0; i < cols.Length; i++) { x += (double)r.Width * cols [i]; gr.MoveTo(Math.Floor(x) + 0.5, 0); gr.LineTo(Math.Floor(x) + 0.5, r.Height); } gr.Stroke(); lastScroll = Scroll; lastHoverIndex = HoverIndex; lastSelectedIndex = SelectedIndex; lastVisibleLines = visibleLines; if (Datas?.Count <= visibleLines) { gr.Restore(); return; } if (mouseScrolling) { new SolidColor(Crow.Color.Jet.AdjustAlpha(0.5)).SetAsSource(gr); } else { new SolidColor(Crow.Color.LightGray.AdjustAlpha(0.5)).SetAsSource(gr); } CairoHelpers.CairoRectangle(gr, scrBar, 0.0); gr.Fill(); new SolidColor(Crow.Color.BlueCrayola.AdjustAlpha(0.7)).SetAsSource(gr); scrBar.Y += (int)((double)scrBar.Height * (double)Scroll / (double)Datas.Count); scrBar.Height = (int)((double)scrBar.Height * (double)visibleLines / (double)Datas.Count); CairoHelpers.CairoRectangle(gr, scrBar, 2.0); gr.Fill(); gr.Restore(); } }
void Draw(Cairo.Context ctx) { int tabArea = tabEndX - tabStartX; int x = GetRenderOffset(); int y = 0; int n = 0; Action <Cairo.Context> drawActive = c => {}; List <Action <Cairo.Context> > drawCommands = new List <Action <Context> > (); for (; n < notebook.Tabs.Count; n++) { if (x + TabWidth < tabStartX) { x += TabWidth; continue; } if (x > tabEndX) { break; } int closingWidth; var cmd = DrawClosingTab(n, new Gdk.Rectangle(x, y, 0, Allocation.Height), out closingWidth); drawCommands.Add(cmd); x += closingWidth; var tab = (DockNotebookTab)notebook.Tabs [n]; bool active = tab == notebook.CurrentTab; int width = Math.Min(TabWidth, Math.Max(50, tabEndX - x - 1)); if (tab == notebook.Tabs.Last()) { width += LastTabWidthAdjustment; } width = (int)(width * tab.WidthModifier); if (active) { int tmp = x; drawActive = c => DrawTab(c, tab, Allocation, new Gdk.Rectangle(tmp, y, width, Allocation.Height), true, true, draggingTab, CreateTabLayout(tab)); tab.Allocation = new Gdk.Rectangle(tmp, Allocation.Y, width, Allocation.Height); } else { int tmp = x; bool highlighted = tab == highlightedTab; if (tab.SaveStrength > 0.0f) { tmp = (int)(tab.SavedAllocation.X + (tmp - tab.SavedAllocation.X) * (1.0f - tab.SaveStrength)); } drawCommands.Add(c => DrawTab(c, tab, Allocation, new Gdk.Rectangle(tmp, y, width, Allocation.Height), highlighted, false, false, CreateTabLayout(tab))); tab.Allocation = new Gdk.Rectangle(tmp, Allocation.Y, width, Allocation.Height); } x += width; } Gdk.Rectangle allocation = Allocation; int tabWidth; drawCommands.Add(DrawClosingTab(n, new Gdk.Rectangle(x, y, 0, allocation.Height), out tabWidth)); drawCommands.Reverse(); DrawBackground(ctx, allocation); // Draw breadcrumb bar header if (notebook.Tabs.Count > 0) { ctx.Rectangle(0, allocation.Height - BottomBarPadding, allocation.Width, BottomBarPadding); ctx.Color = Styles.BreadcrumbBackgroundColor; ctx.Fill(); } ctx.Rectangle(tabStartX - LeanWidth / 2, allocation.Y, tabArea + LeanWidth, allocation.Height); ctx.Clip(); foreach (var cmd in drawCommands) { cmd(ctx); } ctx.ResetClip(); // Redraw the dragging tab here to be sure its on top. We drew it before to get the sizing correct, this should be fixed. drawActive(ctx); }
private void RenderNodeGroup(NodeGroup ng, Network network, Cairo.Context gc) { gc.Save(); SizeD size = CalculateNodeGroupSize(ng, gc); ng.Dimension = size; CreateRoundedRectPath(gc, ng.Position.X, ng.Position.Y, size.Width, size.Height, 20); gc.Color = new Cairo.Color(0, 0, 0, 0.5); gc.FillPreserve(); if (selectedGroup == ng) { gc.Save(); gc.Color = orangeOverlay; gc.StrokePreserve(); gc.Restore(); } var titleTextSize = CalculateNodeGroupTitleTextSize(ng, gc); var titleSize = new SizeD(size.Width, titleTextSize.Height + (Padding * 2.0)); gc.Clip(); gc.Rectangle(ng.Position.X, ng.Position.Y, titleSize.Width, titleSize.Height); gc.Fill(); gc.ResetClip(); gc.Color = lightGray; double hostTextX = ng.Position.X + (titleSize.Width / 2.0) - (titleTextSize.Width / 2.0); double hostTextY = ng.Position.Y + (titleSize.Height / 2.0) - (titleTextSize.Height / 2.0); gc.MoveTo(hostTextX, hostTextY /* + titleTextSize.Height */); Pango.Layout layout = new Pango.Layout(this.PangoContext); layout.FontDescription = this.PangoContext.FontDescription.Copy(); layout.FontDescription.Size = Pango.Units.FromDouble(NodegroupNameFontSize); layout.SetText(ng.Name); Pango.CairoHelper.ShowLayout(gc, layout); SizeD nodesSize = CalculateNodeGroupSize(ng, gc); if (ng.Nodes.Count == 1) { double positionY = ng.Position.Y + titleSize.Height + Padding; double positionX = ng.Position.X + (ng.Dimension.Width / 2.0) - HalfAvatarDimension; RenderNode(gc, (Node)ng.Nodes[0], positionX, positionY); } else if (ng.Nodes.Count == 2) { // position them side-by-side, separated by (padding) number of pixels, centered in the // space. double positionY = ng.Position.Y + titleSize.Height + Padding; double position1X = ng.Position.X + (ng.Dimension.Width / 2.0) - (Padding / 2.0) - AvatarDimension; double position2X = position1X + Padding + AvatarDimension; RenderNode(gc, (Node)ng.Nodes[0], position1X, positionY); RenderNode(gc, (Node)ng.Nodes[1], position2X, positionY); } else { double deg = 0; double x = 0; double y = 0; var contentY = ng.Position.Y + titleSize.Height; var contentHeight = size.Height - titleSize.Height; var middle = new System.Drawing.Point(Convert.ToInt32(ng.Position.X + size.Width - (size.Width / 2.0)), Convert.ToInt32(contentY + contentHeight - (contentHeight / 2.0))); int nodeSize = Convert.ToInt32(AvatarDimension); for (int i = 0; i < ng.Nodes.Count; i++) { x = Math.Sin(deg) * ((size.Width / 2.0) - (nodeSize)) + middle.X - (nodeSize / 2.0); y = Math.Cos(deg) * ((contentHeight / 2.0) - (nodeSize)) + middle.Y - (nodeSize / 2.0); RenderNode(gc, (Node)ng.Nodes[i], x, y); deg += Math.PI / (ng.Nodes.Count / 2.0); } } gc.Restore(); }
void InternalDraw(int markerStart, int markerEnd, MonoTextEditor editor, Cairo.Context cr, LineMetrics metrics, bool selected, int startOffset, int endOffset, double y, double startXPos, double endXPos) { if (markerStart >= markerEnd) { return; } var layout = metrics.Layout.Layout; double @from; double to; if (markerStart < startOffset && endOffset < markerEnd) { @from = startXPos; to = endXPos; } else { int start = Math.Max(startOffset, markerStart); int end = Math.Min(endOffset, markerEnd); int /*lineNr,*/ x_pos; uint curIndex = 0; uint byteIndex = 0; var textLength = metrics.Layout.Text.Length; if (textLength > 0) { uint idx = (uint)Math.Min(Math.Max(0, start - startOffset), textLength - 1); metrics.Layout.TranslateToUTF8Index(idx, ref curIndex, ref byteIndex); x_pos = layout.IndexToPos(System.Math.Max(0, (int)byteIndex)).X; @from = startXPos + (int)(x_pos / Pango.Scale.PangoScale); idx = (uint)Math.Min(Math.Max(0, end - startOffset), textLength - 1); metrics.Layout.TranslateToUTF8Index(idx, ref curIndex, ref byteIndex); x_pos = layout.IndexToPos(System.Math.Max(0, (int)byteIndex)).X; to = startXPos + (int)(x_pos / Pango.Scale.PangoScale); } else { @from = startXPos; to = startXPos + editor.TextViewMargin.CharWidth; } var line = editor.GetLineByOffset(endOffset); if (markerEnd > endOffset || @from == to) { to += editor.TextViewMargin.CharWidth; if (@from >= to) { @from = to - editor.TextViewMargin.CharWidth; } } } @from = System.Math.Max(@from, editor.TextViewMargin.XOffset); to = System.Math.Max(to, editor.TextViewMargin.XOffset); if (Length == 0) { to += editor.TextViewMargin.charWidth; } if (@from >= to) { return; } double height = editor.LineHeight / 5; if (string.IsNullOrEmpty(ColorName)) { cr.SetSourceColor(Color); } else { HslColor color; editor.EditorTheme.TryGetColor(ColorName, out color); cr.SetSourceColor(color); } cr.LineWidth = editor.Options.Zoom; switch (Effect) { case MonoDevelop.Ide.Editor.TextSegmentMarkerEffect.WavedLine: cr.Rectangle(@from, 0, to - @from, editor.Allocation.Height); cr.Clip(); Pango.CairoHelper.ShowErrorUnderline(cr, metrics.TextRenderStartPosition, y + editor.LineHeight - height, editor.Allocation.Width, height); cr.ResetClip(); break; case MonoDevelop.Ide.Editor.TextSegmentMarkerEffect.DottedLine: cr.Save(); cr.MoveTo(@from, y + editor.LineHeight - editor.Options.Zoom - 0.5); cr.LineTo(to, y + editor.LineHeight - editor.Options.Zoom - 0.5); cr.SetDash(new double [] { 2 * editor.Options.Zoom, 2 * editor.Options.Zoom }, 0); cr.Stroke(); cr.Restore(); break; case MonoDevelop.Ide.Editor.TextSegmentMarkerEffect.Underline: cr.MoveTo(@from, y + editor.LineHeight - editor.Options.Zoom - 0.5); cr.LineTo(to, y + editor.LineHeight - editor.Options.Zoom - 0.5); cr.Stroke(); break; default: throw new InvalidOperationException("Invalid text segment marker effect " + Effect + " not supported by this marker."); } }
protected override void ClippedRender(Context cr) { if (!EnsureLayout ()) { return; } Brush foreground = Foreground; if (!foreground.IsValid) { return; } cr.Rectangle (0, 0, RenderSize.Width, RenderSize.Height); cr.Clip (); bool fade = text_alloc.Width > RenderSize.Width; if (fade) { cr.PushGroup (); } cr.MoveTo (text_alloc.X, text_alloc.Y); Foreground.Apply (cr); Pango.CairoHelper.ShowLayout (cr, layout); cr.Fill (); if (fade) { LinearGradient mask = new LinearGradient (RenderSize.Width - 20, 0, RenderSize.Width, 0); mask.AddColorStop (0, new Color (0, 0, 0, 1)); mask.AddColorStop (1, new Color (0, 0, 0, 0)); cr.PopGroupToSource (); cr.Mask (mask); mask.Destroy (); } cr.ResetClip (); }