void Reload () { layout = Layout.Copy (); layout.SetText (ellipsis); layout.GetPixelSize (out ellipsis_width, out tmp); layout.SetText (en_char); layout.GetPixelSize (out en_width, out tmp); }
// int GetTextHeight () // { // int w, h; // layout.GetPixelSize (out w, out h); // return h; // } private void DrawText() { int width, height; GdkWindow.GetSize(out width, out height); int widthPixel, heightPixel; layout.GetPixelSize(out widthPixel, out heightPixel); GdkWindow.DrawLayout(Style.WhiteGC, 0, textTop - scroll, layout); GdkWindow.DrawPixbuf(backGc, monoPowered, 0, 0, (width / 2) - (monoPowered.Width / 2), textTop - scroll + heightPixel + monoLogoSpacing, -1, -1, RgbDither.Normal, 0, 0); heightPixel = heightPixel - 80 + image.Height; if ((scroll == heightPixel) && (scrollPause == 0)) { scrollPause = 60; } if (scroll > heightPixel + monoLogoSpacing + monoPowered.Height) { scroll = scrollStart; } }
///<summary>Constructor</summary> public Drawer(Gtk.Widget wid, Information inf) { widget = wid; info = inf; pixmapIds = new StringCollection(); // make sure highlight colors are set info.SetupHighlight(wid); fontDescription = Pango.FontDescription.FromString(info.FontName); Pango.Language lang = Pango.Language.FromString(info.FontLanguage); Pango.Context pangoCtx = widget.PangoContext; pangoCtx.FontDescription = fontDescription; pangoCtx.Language = lang; // set the font height and width pangoLayout = new Pango.Layout(pangoCtx); // we use a monospaced font, the actual character doesn't matter pangoLayout.SetText("X"); pangoLayout.GetPixelSize(out width, out height); pangoLayout.SetText(""); // create the font pixmaps InitializePixmaps(); InitializeBackgroundGCs(); }
/* * Draw text functions */ // Used for fractions that right align is needed public void DrawTextAlignedRight(double x, double y, string str) { int w, h; Cairo.Matrix old = Matrix; UpdateFontSize(); Matrix = new Cairo.Matrix(); SetText(str); layout.SingleParagraphMode = true; layout.Width = -1; layout.GetPixelSize(out w, out h); MoveTo((old.X0 + x * old.Xx) - w, old.Y0 + y * old.Yy); Pango.CairoHelper.ShowLayout(this, layout); Matrix = old; }
private int GetTextPixelLength(string text, string font) { int width, height; Screen screen = Screen.Default; Pango.Layout layout = new Pango.Layout(PangoHelper.ContextGetForScreen(screen)); layout.FontDescription = Pango.FontDescription.FromString(font); layout.SetText(text); layout.GetPixelSize(out width, out height); return(width); }
void GetMaxSize(out int normal, out int full) { Pango.Layout layout = new Pango.Layout(Gdk.PangoHelper.ContextGet()); normal = full = 0; foreach (EventTypeStats cstat in stats.EventTypeStats) { int width, height; layout.SetMarkup(String.Format("<b>{0}</b>", GLib.Markup.EscapeText(cstat.Name))); layout.GetPixelSize(out width, out height); if (width > normal) { normal = width; } foreach (SubCategoryStat sstat in cstat.SubcategoriesStats) { foreach (PercentualStat spstat in sstat.OptionStats) { layout.SetMarkup(GLib.Markup.EscapeText(String.Format("{0}: {1}", sstat.Name, spstat.Name))); layout.GetPixelSize(out width, out height); if (width > full) { full = width; } } } } if (full < normal) { full = normal; } #if !OSTYPE_LINUX normal = (int)(normal * 1.3); full = (int)(full * 1.3); #endif }
public void DrawLabel(int position, string label) { var layout = new Pango.Layout(this.PangoContext); layout.FontDescription = FontDescription.FromString("Tahoma 16"); layout.SetMarkup(label); int width, height; layout.GetPixelSize(out width, out height); if (width != 0 && height != 0) { _labelPixmap = new Pixmap(GdkWindow, width, height, -1); CalculateXandY(position, width, height); _labelPixmap.DrawDrawable(_gc, _pixmap, _labelX, _labelY, 0, 0, width, height); _labelPixmap.DrawLayout(_gc, 0, 0, layout); QueueDraw(); } }
protected void OnRealized(object o, EventArgs args) { scrollStartPx = imageHeight; layout = new Pango.Layout(this.PangoContext); // FIXME: this seems wrong but works layout.Width = Allocation.Width * (int)Pango.Scale.PangoScale; layout.Wrap = Pango.WrapMode.Word; layout.Alignment = Pango.Alignment.Center; FontDescription fd = FontDescription.FromString("Tahoma 10"); layout.FontDescription = fd; layout.SetMarkup(CreditText); int widthPx, heightPx; layout.GetPixelSize(out widthPx, out heightPx); this.scrollHeightPx = heightPx + monoLogoSpacing + monoPowered.Height + imageHeight / 2; backGc = new Gdk.GC(GdkWindow); backGc.RgbBgColor = bgColor; }
void MeasureLine(IReadonlyTextDocument document, int lineNumber, ref int x, ref int y) { using (var drawingLayout = new Pango.Layout(this.PangoContext)) { drawingLayout.FontDescription = fontDescription; var line = document.GetLine(lineNumber); var indent = line.GetIndentation(document); var curLineIndent = CalcIndentLength(indent); if (line.Length == curLineIndent) { y += lineHeight; return; } if (this.indentLength < 0 || this.indentLength > curLineIndent) { this.indentLength = curLineIndent; } drawingLayout.SetText(document.GetTextAt(line)); int w, h; drawingLayout.GetPixelSize(out w, out h); x = Math.Max(x, w); y += lineHeight; } }
void DrawImage(Gdk.Pixbuf image, double X, double Y, bool highlight) { int x = (int)X - image.Width / 2; int y = (int)Y - image.Height / 2; #if !SYSTEM_DRAWING if (drawer is CairoDrawer) { Cairo.Context context = ((CairoDrawer)drawer).Context; if (highlight) { List <Drawer.Point> points = new List <Drawer.Point>(); points.Add(new Drawer.Point(x - 2.5, y - 2.5)); points.Add(new Drawer.Point(x + image.Width + 1.5, y - 2.5)); points.Add(new Drawer.Point(x + image.Width + 1.5, y + image.Height + 1.5)); points.Add(new Drawer.Point(x - 2.5, y + image.Height + 1.5)); drawer.FillPolygon(new Drawer.Color(1, 1, 0), points); } Gdk.CairoHelper.SetSourcePixbuf(context, image, x, y); context.Paint(); } else { #else { #endif if (highlight) { Gdk.GC gc = new Gdk.GC(GdkWindow); Gdk.Pixmap mask = new Gdk.Pixmap(null, image.Width, image.Height, 1); image.RenderThresholdAlpha(mask, 0, 0, 0, 0, -1, -1, 1); gc.ClipMask = mask; for (int i = -2; i <= 2; ++i) { for (int j = -2; j <= 2; ++j) { gc.SetClipOrigin(x + i, y + j); gc.RgbFgColor = new Gdk.Color(255, 255, 0); GdkWindow.DrawRectangle(gc, true, x + i, y + j, image.Width, image.Height); } } } GdkWindow.DrawPixbuf(new Gdk.GC(GdkWindow), image, 0, 0, x, y, -1, -1, Gdk.RgbDither.Normal, 0, 0); } } void DrawObject(MapObject obj, bool highlight) { if (obj.Type == ObjectType.Player) { if (ShowPlayers) { DrawTriangle(playerColor, Transform.ToScreenX(obj.X), Transform.ToScreenY(obj.Y), obj.Facing, highlight, false); } } else if (obj.Type == ObjectType.Monster) { if (ShowMonsters) { Drawer.Color color; if ((obj.Index >= 12 && obj.Index <= 15) || (obj.Index >= 43 && obj.Index <= 46)) { color = civilianColor; } else { color = monsterColor; } DrawTriangle(color, Transform.ToScreenX(obj.X), Transform.ToScreenY(obj.Y), obj.Facing, highlight, obj.Invisible); } } else if (obj.Type == ObjectType.Scenery) { if (ShowScenery) { DrawImage(sceneryImage, Transform.ToScreenX(obj.X), Transform.ToScreenY(obj.Y), highlight); } } else if (obj.Type == ObjectType.Sound) { if (ShowSounds) { DrawImage(soundImage, Transform.ToScreenX(obj.X), Transform.ToScreenY(obj.Y), highlight); } } else if (obj.Type == ObjectType.Goal) { if (ShowGoals) { DrawImage(goalImage, Transform.ToScreenX(obj.X), Transform.ToScreenY(obj.Y), highlight); } } else if (obj.Type == ObjectType.Item) { if (ShowObjects) { if (itemImages.ContainsKey((ItemType)obj.Index) && itemImages[(ItemType)obj.Index] != null) { DrawImage(itemImages[(ItemType)obj.Index], Transform.ToScreenX(obj.X), Transform.ToScreenY(obj.Y), highlight); } else { drawer.DrawPoint(objectColor, new Drawer.Point(Transform.ToScreenX(obj.X), Transform.ToScreenY(obj.Y))); } } } } void DrawAnnotation(Annotation note, bool selected) { int X = (int)Transform.ToScreenX(note.X); int Y = (int)Transform.ToScreenY(note.Y); Layout layout = new Pango.Layout(this.PangoContext); layout.SetMarkup(note.Text); int width, height; layout.GetPixelSize(out width, out height); this.GdkWindow.DrawLayout(this.Style.TextGC(Gtk.StateType.Normal), X, Y - height, layout); if (selected) { DrawFatPoint(selectedLineColor, new Point(note.X, note.Y)); } else { DrawFatPoint(annotationColor, new Point(note.X, note.Y)); } } Drawer.Color LoadColor(string xPath, Drawer.Color defaultColor) { Drawer.Color c; c.R = Weland.Settings.GetSetting(xPath + "/Red", defaultColor.R); c.G = Weland.Settings.GetSetting(xPath + "/Green", defaultColor.G); c.B = Weland.Settings.GetSetting(xPath + "/Blue", defaultColor.B); return(c); } void SaveColor(string xPath, Drawer.Color c) { Weland.Settings.PutSetting(xPath + "/Red", c.R); Weland.Settings.PutSetting(xPath + "/Green", c.G); Weland.Settings.PutSetting(xPath + "/Blue", c.B); }
protected override bool OnExposeEvent(Gdk.EventExpose args) { using (var context = Gdk.CairoHelper.Create(args.Window)) { context.LineWidth = 1; Gdk.Window window = args.Window; var alloc = Allocation; int width = alloc.Width; int height = alloc.Height; context.Rectangle(args.Area.X, args.Area.Y, args.Area.Width, args.Area.Height); context.Color = this.backgroundColor; context.Fill(); int xpos = iconTextSpacing; int yPos = (int)-vadj.Value; //when there are no matches, display a message to indicate that the completion list is still handling input if (filteredItems.Count == 0) { Gdk.GC gc = new Gdk.GC(window); gc.RgbFgColor = backgroundColor.ToGdkColor(); window.DrawRectangle(gc, true, 0, yPos, width, height - yPos); noMatchLayout.SetText(win.DataProvider.ItemCount == 0 ? NoSuggestionsMsg : NoMatchesMsg); int lWidth, lHeight; noMatchLayout.GetPixelSize(out lWidth, out lHeight); gc.RgbFgColor = (Mono.TextEditor.HslColor)textColor; window.DrawLayout(gc, (width - lWidth) / 2, yPos + (height - lHeight - yPos) / 2 - lHeight, noMatchLayout); gc.Dispose(); return(false); } var textGCNormal = new Gdk.GC(window); textGCNormal.RgbFgColor = (Mono.TextEditor.HslColor)textColor; var fgGCNormal = this.Style.ForegroundGC(StateType.Normal); var matcher = CompletionMatcher.CreateCompletionMatcher(CompletionString); Iterate(true, ref yPos, delegate(Category category, int ypos) { if (ypos >= height) { return; } if (ypos < -rowHeight) { return; } // window.DrawRectangle (this.Style.BackgroundGC (StateType.Insensitive), true, 0, yPos, width, rowHeight); int x = 2; if (category.CompletionCategory != null && !string.IsNullOrEmpty(category.CompletionCategory.Icon)) { var icon = ImageService.GetPixbuf(category.CompletionCategory.Icon, IconSize.Menu); window.DrawPixbuf(fgGCNormal, icon, 0, 0, 0, ypos, icon.Width, icon.Height, Gdk.RgbDither.None, 0, 0); x = icon.Width + 4; } context.Rectangle(0, ypos, Allocation.Width, rowHeight); context.Color = backgroundColor; context.Fill(); // layout.SetMarkup ("<span weight='bold' foreground='#AAAAAA'>" + (category.CompletionCategory != null ? category.CompletionCategory.DisplayText : "Uncategorized") + "</span>"); // window.DrawLayout (textGCInsensitive, x - 1, ypos + 1 + (rowHeight - py) / 2, layout); // layout.SetMarkup ("<span weight='bold'>" + (category.CompletionCategory != null ? category.CompletionCategory.DisplayText : "Uncategorized") + "</span>"); categoryLayout.SetMarkup((category.CompletionCategory != null ? category.CompletionCategory.DisplayText : "Uncategorized")); int px, py; categoryLayout.GetPixelSize(out px, out py); window.DrawLayout(textGCNormal, x, ypos + (rowHeight - py) / 2, categoryLayout); }, delegate(Category curCategory, int item, int itemidx, int ypos) { if (ypos >= height) { return(false); } if (ypos < -rowHeight) { return(true); } const int categoryModeItemIndenting = 0; if (InCategoryMode && curCategory != null && curCategory.CompletionCategory != null) { xpos = iconTextSpacing + categoryModeItemIndenting; } else { xpos = iconTextSpacing; } string markup = win.DataProvider.HasMarkup(item) ? (win.DataProvider.GetMarkup(item) ?? "<null>") : GLib.Markup.EscapeText(win.DataProvider.GetText(item) ?? "<null>"); string description = win.DataProvider.GetDescription(item); if (string.IsNullOrEmpty(description)) { layout.SetMarkup(markup); } else { if (item == SelectedItem) { layout.SetMarkup(markup + " " + description); } else { layout.SetMarkup(markup + " <span foreground=\"darkgray\">" + description + "</span>"); } } string text = win.DataProvider.GetText(item); if (!string.IsNullOrEmpty(text)) { int[] matchIndices = matcher.GetMatch(text); if (matchIndices != null) { Pango.AttrList attrList = layout.Attributes ?? new Pango.AttrList(); for (int newSelection = 0; newSelection < matchIndices.Length; newSelection++) { int idx = matchIndices [newSelection]; var fg = new AttrForeground((ushort)(highlightColor.R * ushort.MaxValue), (ushort)(highlightColor.G * ushort.MaxValue), (ushort)(highlightColor.B * ushort.MaxValue)); fg.StartIndex = (uint)idx; fg.EndIndex = (uint)(idx + 1); attrList.Insert(fg); } layout.Attributes = attrList; } } Gdk.Pixbuf icon = win.DataProvider.GetIcon(item); int iconHeight, iconWidth; if (icon != null) { iconWidth = icon.Width; iconHeight = icon.Height; } else if (!Gtk.Icon.SizeLookup(Gtk.IconSize.Menu, out iconWidth, out iconHeight)) { iconHeight = iconWidth = 24; } int wi, he, typos, iypos; layout.GetPixelSize(out wi, out he); typos = he < rowHeight ? ypos + (rowHeight - he) / 2 : ypos; iypos = iconHeight < rowHeight ? ypos + (rowHeight - iconHeight) / 2 : ypos; if (item == SelectedItem) { context.Rectangle(0, ypos, Allocation.Width, rowHeight / 2); context.Color = SelectionEnabled ? selectedItemColor.Foreground : selectedItemInactiveColor.Background; context.Fill(); context.Rectangle(0, ypos + rowHeight / 2, Allocation.Width, rowHeight / 2); context.Color = SelectionEnabled ? selectedItemColor.Background : selectedItemInactiveColor.Background; context.Fill(); context.Rectangle(0.5, ypos + 0.5, Allocation.Width - 1, rowHeight - 1); if (!SelectionEnabled) { context.SetDash(new double[] { 4, 4 }, 0); } context.Color = SelectionEnabled ? selectionBorderColor : selectionBorderInactiveColor; context.Stroke(); } if (icon != null) { window.DrawPixbuf(fgGCNormal, icon, 0, 0, xpos, iypos, iconWidth, iconHeight, Gdk.RgbDither.None, 0, 0); xpos += iconTextSpacing; } window.DrawLayout(textGCNormal, xpos + iconWidth + 2, typos, layout); if (wi + xpos + iconWidth + 2 > listWidth) { WidthRequest = listWidth = wi + xpos + iconWidth + 2 + iconTextSpacing; win.ResetSizes(); } else { //workaround for the vscrollbar display - the calculated width needs to be the width ofthe render region. if (Allocation.Width < listWidth) { if (listWidth - Allocation.Width < 30) { WidthRequest = listWidth + listWidth - Allocation.Width; win.ResetSizes(); } } } layout.SetMarkup(""); if (layout.Attributes != null) { layout.Attributes.Dispose(); layout.Attributes = null; } return(true); }); /* * int n = 0; * while (ypos < winHeight - margin && (page + n) < filteredItems.Count) { * * bool hasMarkup = win.DataProvider.HasMarkup (filteredItems[page + n]); * if (hasMarkup) { * layout.SetMarkup (win.DataProvider.GetMarkup (filteredItems[page + n]) ?? "<null>"); * } else { * layout.SetText (win.DataProvider.GetText (filteredItems[page + n]) ?? "<null>"); * } * string text = win.DataProvider.GetText (filteredItems[page + n]); * if ((!SelectionEnabled || page + n != selection) && !string.IsNullOrEmpty (text)) { * int[] matchIndices = Match (CompletionString, text); * if (matchIndices != null) { * Pango.AttrList attrList = layout.Attributes ?? new Pango.AttrList (); * for (int newSelection = 0; newSelection < matchIndices.Length; newSelection++) { * int idx = matchIndices[newSelection]; * Pango.AttrForeground fg = new Pango.AttrForeground (0, 0, ushort.MaxValue); * fg.StartIndex = (uint)idx; * fg.EndIndex = (uint)(idx + 1); * attrList.Insert (fg); * } * layout.Attributes = attrList; * } * } * * Gdk.Pixbuf icon = win.DataProvider.GetIcon (filteredItems[page + n]); * int iconHeight, iconWidth; * if (icon != null) { * iconWidth = icon.Width; * iconHeight = icon.Height; * } else if (!Gtk.Icon.SizeLookup (Gtk.IconSize.Menu, out iconWidth, out iconHeight)) { * iconHeight = iconWidth = 24; * } * * int wi, he, typos, iypos; * layout.GetPixelSize (out wi, out he); * typos = he < rowHeight ? ypos + (rowHeight - he) / 2 : ypos; * iypos = iconHeight < rowHeight ? ypos + (rowHeight - iconHeight) / 2 : ypos; * if (page + n == selection) { * if (SelectionEnabled) { * window.DrawRectangle (this.Style.BaseGC (StateType.Selected), true, margin, ypos, lineWidth, he + padding); * window.DrawLayout (this.Style.TextGC (StateType.Selected), xpos + iconWidth + 2, typos, layout); * } else { * window.DrawRectangle (this.Style.DarkGC (StateType.Prelight), false, margin, ypos, lineWidth - 1, he + padding - 1); * window.DrawLayout (this.Style.TextGC (StateType.Normal), xpos + iconWidth + 2, typos, layout); * } * } else * window.DrawLayout (this.Style.TextGC (StateType.Normal), xpos + iconWidth + 2, typos, layout); * if (icon != null) * window.DrawPixbuf (this.Style.ForegroundGC (StateType.Normal), icon, 0, 0, xpos, iypos, iconWidth, iconHeight, Gdk.RgbDither.None, 0, 0); * ypos += rowHeight; * n++; * if (hasMarkup) * layout.SetMarkup (string.Empty); * if (layout.Attributes != null) { * layout.Attributes.Dispose (); * layout.Attributes = null; * } * } */ return(false); } }
/// <summary> /// Called when the widget is exposed or drawn. /// </summary> /// <param name="e">The e.</param> /// <returns></returns> protected override bool OnExposeEvent(EventExpose e) { // Figure out the area we are rendering into. Gdk.Rectangle area = e.Region.Clipbox; var cairoArea = new Rectangle(area.X, area.Y, area.Width, area.Height); using (Context cairoContext = CairoHelper.Create(e.Window)) { // Create a render context. var renderContext = new RenderContext(cairoContext); renderContext.RenderRegion = cairoArea; // If we don't have a buffer at this point, don't render anything. if (Renderer == null || LineBuffer == null) { return(true); } // Paint the background color of the window. RegionBlockStyle backgroundStyle = Theme.RegionStyles[Theme.BackgroundRegionStyleName]; DrawingUtility.DrawLayout(this, renderContext, cairoArea, backgroundStyle); // Reset the layout and its properties. Renderer.Width = area.Width - margins.Width; // Figure out the viewport area we'll be drawing. int offsetY = 0; if (verticalAdjustment != null) { offsetY += (int)verticalAdjustment.Value; } var viewArea = new Rectangle( area.X, area.Y + offsetY, area.Width, area.Height); // Determine the line range visible in the given area. int startLine, endLine; Renderer.GetLineLayoutRange(viewArea, out startLine, out endLine); // Determine where the first line actually starts. int startLineY = 0; if (startLine > 0) { startLineY = Renderer.GetLineLayoutHeight(0, startLine - 1); } // Go through the lines and draw each one in the correct position. double currentY = startLineY - offsetY; for (int lineIndex = startLine; lineIndex <= endLine; lineIndex++) { // Figure out if we are on the current line. var lineContexts = LineContexts.None; bool currentLine = false; if (lineIndex == caret.Position.LinePosition) { // Add the curent line to the context. lineContexts |= LineContexts.CurrentLine; currentLine = true; } // Pull out the layout and style since we'll use it. Layout layout = Renderer.GetLineLayout(lineIndex, lineContexts); LineBlockStyle style = Renderer.GetLineStyle(lineIndex, lineContexts); // Get the extents for that line. int layoutWidth, layoutHeight; layout.GetPixelSize(out layoutWidth, out layoutHeight); // Figure out the height of the line including padding. double height = layoutHeight + style.Height; if (currentLine) { // If we have a full-line background color, display it. RegionBlockStyle currentLineStyle = Theme.RegionStyles[Theme.CurrentLineRegionStyleName]; if (currentLineStyle != null) { var lineArea = new Rectangle(TextX, currentY, TextWidth, height); DrawingUtility.DrawLayout( this, renderContext, lineArea, currentLineStyle); } // If we have a wrapped line background color, draw it. RegionBlockStyle currentWrappedLineStyle = Theme.RegionStyles[Theme.CurrentWrappedLineRegionStyleName]; if (currentWrappedLineStyle != null) { // Get the wrapped line for the caret's position. LayoutLine wrappedLine = caret.Position.GetWrappedLine(this); Pango.Rectangle wrappedLineExtents; wrappedLine.GetPixelExtents(out wrappedLineExtents); // Draw the current wrapped line index. var wrappedLineArea = new Rectangle( TextX, currentY + wrappedLineExtents.Y + style.Top, TextWidth, wrappedLineExtents.Height); DrawingUtility.DrawLayout( this, renderContext, wrappedLineArea, currentWrappedLineStyle); } } // Draw the current line along with wrapping and padding. DrawingUtility.DrawLayout( this, renderContext, new Rectangle(TextX, currentY, TextWidth, height), layout, style); // Render out the margin renderers. margins.Draw( this, renderContext, lineIndex, new PointD(0, currentY), height, style); // Move down a line. currentY += height; } // Draw the caret on the screen, but only if we have focus. if (IsFocus) { caret.Draw(renderContext); } // Show the scroll region, if requested. if (editorViewSettings.ShowScrollPadding) { cairoContext.Color = new Color(1, 0.5, 0.5); cairoContext.Rectangle(scrollPaddingRegion); cairoContext.Stroke(); } } return(true); }
protected void OnRealized (object o, EventArgs args) { scrollStartPx = imageHeight; layout = new Pango.Layout (this.PangoContext); // FIXME: this seems wrong but works layout.Width = Allocation.Width * (int)Pango.Scale.PangoScale; layout.Wrap = Pango.WrapMode.Word; layout.Alignment = Pango.Alignment.Center; FontDescription fd = FontDescription.FromString ("Tahoma 10"); layout.FontDescription = fd; layout.SetMarkup (CreditText); int widthPx, heightPx; layout.GetPixelSize (out widthPx, out heightPx); this.scrollHeightPx = heightPx + monoLogoSpacing + monoPowered.Height + imageHeight / 2; backGc = new Gdk.GC (GdkWindow); backGc.RgbBgColor = bgColor; }
void DrawPolygon(short polygon_index, PolygonColor color) { Polygon polygon = Level.Polygons[polygon_index]; List <Drawer.Point> points = new List <Drawer.Point>(); for (int i = 0; i < polygon.VertexCount; ++i) { points.Add(Transform.ToScreenPoint(Level.Endpoints[polygon.EndpointIndexes[i]])); } if (Mode == DrawMode.FloorHeight) { drawer.FillPolygon(PaintColors[polygon.FloorHeight], points); } else if (Mode == DrawMode.CeilingHeight) { drawer.FillPolygon(PaintColors[polygon.CeilingHeight], points); } else if (Mode == DrawMode.PolygonType) { drawer.FillPolygon(PaintColors[(short)polygon.Type], points); } else if (Mode == DrawMode.FloorLight) { drawer.FillPolygon(PaintColors[(short)polygon.FloorLight], points); } else if (Mode == DrawMode.CeilingLight) { drawer.FillPolygon(PaintColors[(short)polygon.CeilingLight], points); } else if (Mode == DrawMode.MediaLight) { drawer.FillPolygon(PaintColors[(short)polygon.MediaLight], points); } else if (Mode == DrawMode.Media) { drawer.FillPolygon(PaintColors[(short)polygon.MediaIndex], points); } else if (Mode == DrawMode.AmbientSound) { drawer.FillPolygon(PaintColors[(short)polygon.AmbientSound], points); } else if (Mode == DrawMode.RandomSound) { drawer.FillPolygon(PaintColors[(short)polygon.RandomSound], points); } else if (Mode == DrawMode.FloorTexture) { drawer.TexturePolygon(polygon.FloorTexture, points); } else if (Mode == DrawMode.CeilingTexture) { drawer.TexturePolygon(polygon.CeilingTexture, points); } else { if (color == PolygonColor.Selected) { drawer.FillPolygon(selectedPolygonColor, points); } else if (color == PolygonColor.Destination) { drawer.FillPolygon(destinationPolygonColor, points); } else if (polygon.Concave) { drawer.FillPolygon(invalidPolygonColor, points); } else { drawer.FillPolygon(polygonColor, points); } } if (Mode == DrawMode.Draw && polygon.Type == PolygonType.Platform) { Drawer.Point center = Transform.ToScreenPoint(Level.PolygonCenter(polygon)); Layout layout = new Pango.Layout(this.PangoContext); layout.SetMarkup(String.Format("{0}", polygon_index)); int width, height; layout.GetPixelSize(out width, out height); this.GdkWindow.DrawLayout(this.Style.TextGC(Gtk.StateType.Normal), (int)center.X - width / 2, (int)center.Y - height / 2, layout); } }
protected override void Render(Gdk.Drawable drawable, Widget widget, Gdk.Rectangle background_area, Gdk.Rectangle cell_area, Gdk.Rectangle expose_area, CellRendererState flags) { StateType state = RendererStateToWidgetState(flags); int text_indent = 6; int text_layout_width, text_layout_height; Gdk.Pixbuf render_icon = radio_icon; Track track = null; RadioTrackInfo radio_track = null; string text = Text; if (widget is TreeView) { TreePath path; if ((widget as TreeView).GetPathAtPos(cell_area.X, cell_area.Y, out path)) { track = model.GetTrack(path); radio_track = model.GetRadioTrackInfo(path); } } FontDescription font_description = widget.PangoContext.FontDescription.Copy(); if (playing_icon != null && track != null && PlayerEngineCore.CurrentTrack is RadioTrackInfo && (PlayerEngineCore.CurrentTrack as RadioTrackInfo).XspfTrack.Title == track.Title && (PlayerEngineCore.CurrentTrack as RadioTrackInfo).XspfTrack.Annotation == track.Annotation) { render_icon = playing_icon; font_description.Style = Pango.Style.Normal; font_description.Weight = Pango.Weight.Bold; } else if (radio_track != null && radio_track.ParsingPlaylist) { render_icon = loading_icon; font_description.Style = Pango.Style.Italic; font_description.Weight = Pango.Weight.Normal; text = String.Format("{0}: {1}", Catalog.GetString("Loading"), Text); } else if (radio_track != null && radio_track.PlaybackError != TrackPlaybackError.None) { render_icon = error_icon; font_description.Style = Pango.Style.Italic; font_description.Weight = Pango.Weight.Normal; string prefix = null; switch (radio_track.PlaybackError) { case TrackPlaybackError.ResourceNotFound: prefix = Catalog.GetString("Missing"); break; case TrackPlaybackError.CodecNotFound: prefix = Catalog.GetString("No Codec"); break; case TrackPlaybackError.Unknown: prefix = Catalog.GetString("Unknown Error"); break; default: break; } if (prefix != null) { text = String.Format("({0}) {1}", prefix, Text); } if (!(CellRendererState.Selected & flags).Equals(CellRendererState.Selected)) { state = StateType.Insensitive; } if (track != null) { track.Title = String.Empty; } } else { font_description.Style = Pango.Style.Normal; font_description.Weight = Pango.Weight.Normal; } Gdk.GC main_gc = widget.Style.TextGC(state); if (track != null) { drawable.DrawPixbuf(main_gc, render_icon, 0, 0, cell_area.X - render_icon.Width, cell_area.Y + ((cell_area.Height - render_icon.Height) / 2), render_icon.Width, render_icon.Height, RgbDither.None, 0, 0); } else { text_indent = 0; } Pango.Layout text_layout = new Pango.Layout(widget.PangoContext); text_layout.FontDescription = font_description; text_layout.SetMarkup(GLib.Markup.EscapeText(text)); text_layout.GetPixelSize(out text_layout_width, out text_layout_height); drawable.DrawLayout(main_gc, cell_area.X + text_indent, cell_area.Y + ((cell_area.Height - text_layout_height) / 2), text_layout); }
protected override void Render(Gdk.Drawable drawable, Widget widget, Gdk.Rectangle background_area, Gdk.Rectangle cell_area, Gdk.Rectangle expose_area, CellRendererState flags) { StateType state = RendererStateToWidgetState(flags); int text_indent = 6; int text_layout_width, text_layout_height; Gdk.Pixbuf render_icon = radio_icon; Track track = null; RadioTrackInfo radio_track = null; string text = Text; if(widget is TreeView) { TreePath path; if((widget as TreeView).GetPathAtPos(cell_area.X, cell_area.Y, out path)) { track = model.GetTrack(path); radio_track = model.GetRadioTrackInfo(path); } } FontDescription font_description = widget.PangoContext.FontDescription.Copy(); if(playing_icon != null && track != null && PlayerEngineCore.CurrentTrack is RadioTrackInfo && (PlayerEngineCore.CurrentTrack as RadioTrackInfo).XspfTrack.Title == track.Title && (PlayerEngineCore.CurrentTrack as RadioTrackInfo).XspfTrack.Annotation == track.Annotation) { render_icon = playing_icon; font_description.Style = Pango.Style.Normal; font_description.Weight = Pango.Weight.Bold; } else if(radio_track != null && radio_track.ParsingPlaylist) { render_icon = loading_icon; font_description.Style = Pango.Style.Italic; font_description.Weight = Pango.Weight.Normal; text = String.Format("{0}: {1}", Catalog.GetString("Loading"), Text); } else if(radio_track != null && radio_track.PlaybackError != TrackPlaybackError.None) { render_icon = error_icon; font_description.Style = Pango.Style.Italic; font_description.Weight = Pango.Weight.Normal; string prefix = null; switch(radio_track.PlaybackError) { case TrackPlaybackError.ResourceNotFound: prefix = Catalog.GetString("Missing"); break; case TrackPlaybackError.CodecNotFound: prefix = Catalog.GetString("No Codec"); break; case TrackPlaybackError.Unknown: prefix = Catalog.GetString("Unknown Error"); break; default: break; } if(prefix != null) { text = String.Format("({0}) {1}", prefix, Text); } if(!(CellRendererState.Selected & flags).Equals(CellRendererState.Selected)) { state = StateType.Insensitive; } if(track != null) { track.Title = String.Empty; } } else { font_description.Style = Pango.Style.Normal; font_description.Weight = Pango.Weight.Normal; } Gdk.GC main_gc = widget.Style.TextGC(state); if(track != null) { drawable.DrawPixbuf(main_gc, render_icon, 0, 0, cell_area.X - render_icon.Width, cell_area.Y + ((cell_area.Height - render_icon.Height) / 2), render_icon.Width, render_icon.Height, RgbDither.None, 0, 0); } else { text_indent = 0; } Pango.Layout text_layout = new Pango.Layout(widget.PangoContext); text_layout.FontDescription = font_description; text_layout.SetMarkup(GLib.Markup.EscapeText(text)); text_layout.GetPixelSize(out text_layout_width, out text_layout_height); drawable.DrawLayout(main_gc, cell_area.X + text_indent, cell_area.Y + ((cell_area.Height - text_layout_height) / 2), text_layout); }
public static string Ellipsize(Pango.Layout layout, string newtext, int bound, int ellipsis_width, int en_width, int hAdjust) { int width, tmp; layout.SetText(newtext); layout.GetPixelSize(out width, out tmp); if (bound <= ellipsis_width) { return(ellipsis); } string ellipsized = ""; int i = 0; if (hAdjust != 0) { i += hAdjust; while (i < newtext.Length) { ellipsized = ellipsized + newtext[i]; layout.SetText(ellipsized); layout.GetPixelSize(out width, out tmp); if (width > bound - ellipsis_width) { break; } i++; } return(ellipsized); } if (width < bound) { return(newtext); } //make a guess of where to start i = (bound - ellipsis_width) / (en_width); if (i >= newtext.Length) { i = 0; } ellipsized = newtext.Substring(hAdjust, i); //add chars one by one to determine how many are allowed while (true) { ellipsized = ellipsized + newtext[i]; layout.SetText(ellipsized); layout.GetPixelSize(out width, out tmp); if (i == newtext.Length - 1) { //bad guess, start from the beginning ellipsized = ""; i = 0; continue; } if (width > bound - ellipsis_width) { break; } i++; } ellipsized = ellipsized.Remove(ellipsized.Length - 1, 1); ellipsized += ellipsis; return(ellipsized); }
//FIXME: we could use the expose event's clipbox to make the drawing more efficient void DrawList(Gdk.EventExpose args) { var window = args.Window; int winWidth, winHeight; window.GetSize(out winWidth, out winHeight); int ypos = margin; int lineWidth = winWidth - margin * 2; int xpos = margin + padding - (int)hAdjustement.Value; //avoid recreating the GC objects that we use multiple times var textGCNormal = this.Style.TextGC(StateType.Normal); var fgGCNormal = this.Style.ForegroundGC(StateType.Normal); int n = 0; while (ypos < winHeight - margin && (page + n) < RowCount) { bool isSelected = selectedRows.Contains(page + n); bool hasMarkup = SetLayoutText(page + n, isSelected); Gdk.Pixbuf icon = dataProvider.GetIcon(page + n); int iconHeight = icon != null? icon.Height : IconWidth; int iconWidth = icon != null? icon.Width : IconWidth; int wi, he, typos, iypos; layout.GetPixelSize(out wi, out he); typos = he < rowHeight ? ypos + (rowHeight - he) / 2 : ypos; iypos = iconHeight < rowHeight ? ypos + (rowHeight - iconHeight) / 2 : ypos; if (isSelected) { if (!disableSelection) { window.DrawRectangle(this.Style.BaseGC(StateType.Selected), true, margin, ypos, lineWidth, he + padding); window.DrawLayout(this.Style.TextGC(StateType.Selected), xpos + iconWidth + ColumnGap, typos, layout); } else { window.DrawRectangle(this.Style.BaseGC(StateType.Selected), false, margin, ypos, lineWidth, he + padding); window.DrawLayout(textGCNormal, xpos + iconWidth + ColumnGap, typos, layout); } // Draw a 'most recent selection' rectangle. if (this.SelectedRow == page + n) { window.DrawRectangle(this.Style.BaseGC(StateType.Active), false, margin, ypos, lineWidth, he + padding - 1); window.DrawLayout(this.Style.TextGC(StateType.Active), xpos + iconWidth + ColumnGap, typos, layout); } } else { window.DrawLayout(textGCNormal, xpos + iconWidth + ColumnGap, typos, layout); } if (icon != null) { window.DrawPixbuf(fgGCNormal, icon, 0, 0, xpos, iypos, iconWidth, iconHeight, RgbDither.None, 0, 0); } ypos += rowHeight; n++; //reset the markup or it carries over to the next SetText if (hasMarkup) { layout.SetMarkup(string.Empty); } } }
protected override bool OnExposeEvent(Gdk.EventExpose args) { using (var context = Gdk.CairoHelper.Create(args.Window)) { context.LineWidth = 1; var alloc = Allocation; int width = alloc.Width; int height = alloc.Height; context.Rectangle(args.Area.X, args.Area.Y, args.Area.Width, args.Area.Height); var backgroundColor = ColorScheme.CompletionWindow.Color; var textColor = ColorScheme.GetForeground(ColorScheme.CompletionText); context.SetSourceColor(backgroundColor); context.Fill(); int xpos = iconTextSpacing; int yPos = (int)-vadj.Value; //when there are no matches, display a message to indicate that the completion list is still handling input if (filteredItems.Count == 0) { context.Rectangle(0, yPos, width, height - yPos); context.SetSourceColor(backgroundColor); context.Stroke(); noMatchLayout.SetText(win.DataProvider.ItemCount == 0 ? NoSuggestionsMsg : NoMatchesMsg); int lWidth, lHeight; noMatchLayout.GetPixelSize(out lWidth, out lHeight); context.SetSourceColor(textColor); context.MoveTo((width - lWidth) / 2, yPos + (height - lHeight - yPos) / 2 - lHeight); Pango.CairoHelper.ShowLayout(context, noMatchLayout); return(false); } var matcher = CompletionMatcher.CreateCompletionMatcher(CompletionString); Iterate(true, ref yPos, delegate(Category category, int ypos) { if (ypos >= height) { return; } if (ypos < -rowHeight) { return; } // window.DrawRectangle (this.Style.BackgroundGC (StateType.Insensitive), true, 0, yPos, width, rowHeight); int x = 2; if (category.CompletionCategory != null && !string.IsNullOrEmpty(category.CompletionCategory.Icon)) { var icon = ImageService.GetIcon(category.CompletionCategory.Icon, IconSize.Menu); context.DrawImage(this, icon, 0, ypos); x = (int)icon.Width + 4; } context.Rectangle(0, ypos, Allocation.Width, rowHeight); context.SetSourceColor(backgroundColor); context.Fill(); // layout.SetMarkup ("<span weight='bold' foreground='#AAAAAA'>" + (category.CompletionCategory != null ? category.CompletionCategory.DisplayText : "Uncategorized") + "</span>"); // window.DrawLayout (textGCInsensitive, x - 1, ypos + 1 + (rowHeight - py) / 2, layout); // layout.SetMarkup ("<span weight='bold'>" + (category.CompletionCategory != null ? category.CompletionCategory.DisplayText : "Uncategorized") + "</span>"); categoryLayout.SetMarkup((category.CompletionCategory != null ? category.CompletionCategory.DisplayText : "Uncategorized")); int px, py; categoryLayout.GetPixelSize(out px, out py); context.MoveTo(x, ypos + (rowHeight - py) / 2); context.SetSourceColor(textColor); Pango.CairoHelper.ShowLayout(context, categoryLayout); }, delegate(Category curCategory, int item, int itemidx, int ypos) { if (ypos >= height) { return(false); } if (ypos < -rowHeight) { return(true); } const int categoryModeItemIndenting = 0; if (InCategoryMode && curCategory != null && curCategory.CompletionCategory != null) { xpos = iconTextSpacing + categoryModeItemIndenting; } else { xpos = iconTextSpacing; } string markup = win.DataProvider.HasMarkup(item) ? (win.DataProvider.GetMarkup(item) ?? "<null>") : GLib.Markup.EscapeText(win.DataProvider.GetText(item) ?? "<null>"); string description = win.DataProvider.GetDescription(item, item == SelectedItem); if (string.IsNullOrEmpty(description)) { layout.SetMarkup(markup); } else { layout.SetMarkup(markup + " " + description); } string text = win.DataProvider.GetText(item); if (!string.IsNullOrEmpty(text)) { int [] matchIndices = matcher.GetMatch(text); if (matchIndices != null) { Pango.AttrList attrList = layout.Attributes ?? new Pango.AttrList(); for (int newSelection = 0; newSelection < matchIndices.Length; newSelection++) { int idx = matchIndices [newSelection]; ChunkStyle stringStyle; if (item == SelectedItem) { stringStyle = ColorScheme.CompletionSelectedMatchingSubstring; } else { stringStyle = ColorScheme.CompletionMatchingSubstring; } var highlightColor = (Cairo.Color)ColorScheme.GetForeground(stringStyle); var fg = new AttrForeground((ushort)(highlightColor.R * ushort.MaxValue), (ushort)(highlightColor.G * ushort.MaxValue), (ushort)(highlightColor.B * ushort.MaxValue)); fg.StartIndex = (uint)idx; fg.EndIndex = (uint)(idx + 1); attrList.Insert(fg); if (stringStyle.FontWeight != FontWeight.Normal) { var variant = new AttrWeight((Pango.Weight)stringStyle.FontWeight); variant.StartIndex = (uint)idx; variant.EndIndex = (uint)(idx + 1); attrList.Insert(variant); } } layout.Attributes = attrList; } } Xwt.Drawing.Image icon = win.DataProvider.GetIcon(item); int iconHeight, iconWidth; if (icon != null) { iconWidth = (int)icon.Width; iconHeight = (int)icon.Height; } else if (!Gtk.Icon.SizeLookup(IconSize.Menu, out iconWidth, out iconHeight)) { iconHeight = iconWidth = 24; } int wi, he, typos, iypos; layout.GetPixelSize(out wi, out he); typos = he < rowHeight ? ypos + (int)Math.Ceiling((rowHeight - he) / 2.0) : ypos; iypos = iconHeight < rowHeight ? ypos + (rowHeight - iconHeight) / 2 : ypos; if (item == SelectedItem) { context.Rectangle(0, ypos, Allocation.Width, rowHeight / 2); var barStyle = SelectionEnabled ? ColorScheme.CompletionSelectionBarBackground : ColorScheme.CompletionSelectionBarBackgroundInactive; var barBorderStyle = SelectionEnabled ? ColorScheme.CompletionSelectionBarBorder : ColorScheme.CompletionSelectionBarBorderInactive; context.SetSourceColor(barStyle.Color); context.Fill(); context.Rectangle(0, ypos + rowHeight / 2, Allocation.Width, rowHeight / 2); context.SetSourceColor(barStyle.SecondColor); context.Fill(); context.Rectangle(0.5, ypos + 0.5, Allocation.Width - 1, rowHeight - 1); if (!SelectionEnabled) { context.SetDash(new double[] { 4, 4 }, 0); } context.SetSourceColor(barBorderStyle.Color); context.Stroke(); } if (icon != null) { context.DrawImage(this, icon, xpos, iypos); xpos += iconTextSpacing; } context.SetSourceColor(item == SelectedItem ? ColorScheme.GetForeground(ColorScheme.CompletionSelectedText) : textColor); var textXPos = xpos + iconWidth + 2; context.MoveTo(textXPos, typos); layout.Width = (int)((Allocation.Width - textXPos) * Pango.Scale.PangoScale); layout.Ellipsize = EllipsizeMode.End; Pango.CairoHelper.ShowLayout(context, layout); layout.Width = -1; layout.Ellipsize = EllipsizeMode.None; layout.SetMarkup(""); if (layout.Attributes != null) { layout.Attributes.Dispose(); layout.Attributes = null; } string rightText = win.DataProvider.GetRightSideDescription(item, item == SelectedItem); if (!string.IsNullOrEmpty(rightText)) { layout.SetMarkup(rightText); int w, h; layout.GetPixelSize(out w, out h); wi += w; typos = h < rowHeight ? ypos + (rowHeight - h) / 2 : ypos; context.MoveTo(Allocation.Width - w, typos); Pango.CairoHelper.ShowLayout(context, layout); } if (Math.Min(maxListWidth, wi + xpos + iconWidth + 2) > listWidth) { WidthRequest = listWidth = Math.Min(maxListWidth, wi + xpos + iconWidth + 2 + iconTextSpacing); win.ResetSizes(); } else { //workaround for the vscrollbar display - the calculated width needs to be the width ofthe render region. if (Allocation.Width < listWidth) { if (listWidth - Allocation.Width < 30) { WidthRequest = listWidth + listWidth - Allocation.Width; win.ResetSizes(); } } } return(true); }); return(false); } }
private void plotCurvesGraphDoPlotMessage(string message) { Pango.Layout layout_message = new Pango.Layout (encoder_capture_curves_bars_drawingarea.PangoContext); layout_message.FontDescription = Pango.FontDescription.FromString ("Courier 10"); int graphWidth=encoder_capture_curves_bars_drawingarea.Allocation.Width; int graphHeight=encoder_capture_curves_bars_drawingarea.Allocation.Height; layout_message.SetMarkup(message); int textWidth = 1; int textHeight = 1; layout_message.GetPixelSize(out textWidth, out textHeight); int xStart = Convert.ToInt32(graphWidth/2 - textWidth/2); int yStart = Convert.ToInt32(graphHeight/2 - textHeight/2); //draw horizontal line behind (across all graph) Rectangle rect = new Rectangle(0, yStart + textHeight -1, graphWidth, 1); encoder_capture_curves_bars_pixmap.DrawRectangle(pen_yellow_encoder_capture, true, rect); //draw rectangle behind text rect = new Rectangle(xStart -2, yStart -2, textWidth +2, textHeight +2); encoder_capture_curves_bars_pixmap.DrawRectangle(pen_yellow_encoder_capture, true, rect); //write text inside encoder_capture_curves_bars_pixmap.DrawLayout (pen_black_encoder_capture, xStart, yStart, layout_message); }
public void DrawLabel(int position, string label) { var layout = new Pango.Layout(this.PangoContext); layout.FontDescription = FontDescription.FromString ("Tahoma 16"); layout.SetMarkup(label); int width, height; layout.GetPixelSize(out width, out height); if (width != 0 && height != 0) { _labelPixmap = new Pixmap(GdkWindow, width, height, -1); CalculateXandY(position, width, height); _labelPixmap.DrawDrawable(_gc, _pixmap, _labelX, _labelY, 0, 0, width, height); _labelPixmap.DrawLayout(_gc, 0, 0, layout); QueueDraw(); } }
protected override void Render (Gdk.Drawable drawable, Widget widget, Gdk.Rectangle background_area, Gdk.Rectangle cell_area, Gdk.Rectangle expose_area, CellRendererState flags) { if (source == null) { return; } view = widget as SourceView; bool selected = view != null && view.Selection.IterIsSelected (iter); StateType state = RendererStateToWidgetState (widget, flags); RenderSelection (drawable, background_area, selected, state); int title_layout_width = 0, title_layout_height = 0; int count_layout_width = 0, count_layout_height = 0; int max_title_layout_width; bool hide_counts = source.EnabledCount <= 0; Pixbuf icon = SourceIconResolver.ResolveIcon (source, RowHeight); bool dispose_icon = false; if (state == StateType.Insensitive) { // Code ported from gtk_cell_renderer_pixbuf_render() var icon_source = new IconSource () { Pixbuf = icon, Size = IconSize.SmallToolbar, SizeWildcarded = false }; icon = widget.Style.RenderIcon (icon_source, widget.Direction, state, (IconSize)(-1), widget, "SourceRowRenderer"); dispose_icon = true; icon_source.Dispose (); } FontDescription fd = widget.PangoContext.FontDescription.Copy (); fd.Weight = (ISource)ServiceManager.PlaybackController.NextSource == (ISource)source ? Pango.Weight.Bold : Pango.Weight.Normal; if (view != null && source == view.NewPlaylistSource) { fd.Style = Pango.Style.Italic; hide_counts = true; } Pango.Layout title_layout = new Pango.Layout (widget.PangoContext); Pango.Layout count_layout = null; if (!hide_counts) { count_layout = new Pango.Layout (widget.PangoContext); count_layout.FontDescription = fd; count_layout.SetMarkup (String.Format ("<span size=\"small\">{0}</span>", source.EnabledCount)); count_layout.GetPixelSize (out count_layout_width, out count_layout_height); } max_title_layout_width = cell_area.Width - (icon == null ? 0 : icon.Width) - count_layout_width - 10; if (!hide_counts && max_title_layout_width < 0) { hide_counts = true; } title_layout.FontDescription = fd; title_layout.Width = (int)(max_title_layout_width * Pango.Scale.PangoScale); title_layout.Ellipsize = EllipsizeMode.End; title_layout.SetText (source.Name); title_layout.GetPixelSize (out title_layout_width, out title_layout_height); Gdk.GC main_gc = widget.Style.TextGC (state); drawable.DrawLayout (main_gc, cell_area.X + (icon == null ? 0 : icon.Width) + 6, Middle (cell_area, title_layout_height), title_layout); title_layout.Dispose (); if (icon != null) { drawable.DrawPixbuf (main_gc, icon, 0, 0, cell_area.X, Middle (cell_area, icon.Height), icon.Width, icon.Height, RgbDither.None, 0, 0); if (dispose_icon) { icon.Dispose (); } } if (hide_counts) { fd.Dispose (); return; } if (view != null && view.Cr != null) { view.Cr.Color = state == StateType.Normal || (view != null && state == StateType.Prelight) ? view.Theme.TextMidColor : view.Theme.Colors.GetWidgetColor (GtkColorClass.Text, state); view.Cr.MoveTo ( cell_area.X + cell_area.Width - count_layout_width - 2, cell_area.Y + 0.5 + (double)(cell_area.Height - count_layout_height) / 2.0); PangoCairoHelper.ShowLayout (view.Cr, count_layout); } count_layout.Dispose (); fd.Dispose (); }
protected override bool OnExposeEvent(Gdk.EventExpose args) { Gdk.Window window = args.Window; var alloc = Allocation; int width = alloc.Width; int height = alloc.Height; int lineWidth = width - margin * 2; int xpos = margin + padding; int yPos = margin; if (PreviewCompletionString) { layout.SetText(string.IsNullOrEmpty(CompletionString) ? MonoDevelop.Core.GettextCatalog.GetString("Select template") : CompletionString); int wi, he; layout.GetPixelSize(out wi, out he); window.DrawRectangle(this.Style.BaseGC(StateType.Insensitive), true, margin, yPos, lineWidth, he + padding); window.DrawLayout(string.IsNullOrEmpty(CompletionString) ? this.Style.TextGC(StateType.Insensitive) : this.Style.TextGC(StateType.Normal), xpos, yPos, layout); yPos += rowHeight; } //when there are no matches, display a message to indicate that the completion list is still handling input if (filteredItems.Count == 0) { Gdk.GC gc = new Gdk.GC(window); gc.RgbFgColor = new Gdk.Color(0xff, 0xbc, 0xc1); window.DrawRectangle(gc, true, 0, yPos, width, height - yPos); gc.Dispose(); layout.SetText(win.DataProvider.ItemCount == 0? NoSuggestionsMsg : NoMatchesMsg); int lWidth, lHeight; layout.GetPixelSize(out lWidth, out lHeight); window.DrawLayout(this.Style.TextGC(StateType.Normal), (width - lWidth) / 2, yPos + (height - lHeight - yPos) / 2, layout); return(true); } var textGCInsensitive = this.Style.TextGC(StateType.Insensitive); var textGCNormal = this.Style.TextGC(StateType.Normal); var fgGCNormal = this.Style.ForegroundGC(StateType.Normal); Iterate(true, ref yPos, delegate(Category category, int ypos) { if (ypos >= height - margin) { return; } // window.DrawRectangle (this.Style.BackgroundGC (StateType.Insensitive), true, 0, yPos, width, rowHeight); Gdk.Pixbuf icon = ImageService.GetPixbuf(category.CompletionCategory.Icon, IconSize.Menu); window.DrawPixbuf(fgGCNormal, icon, 0, 0, margin, ypos, icon.Width, icon.Height, Gdk.RgbDither.None, 0, 0); layout.SetMarkup("<span weight='bold'>" + category.CompletionCategory.DisplayText + "</span>"); window.DrawLayout(textGCInsensitive, icon.Width + 4, ypos, layout); layout.SetMarkup(""); }, delegate(Category curCategory, int item, int ypos) { if (ypos >= height - margin) { return(false); } int itemIndex = filteredItems[item]; if (InCategoryMode && curCategory != null && curCategory.CompletionCategory != null) { xpos = margin + padding + 8; } else { xpos = margin + padding; } string markup = win.DataProvider.HasMarkup(itemIndex) ? (win.DataProvider.GetMarkup(itemIndex) ?? "<null>") : GLib.Markup.EscapeText(win.DataProvider.GetText(itemIndex) ?? "<null>"); string description = win.DataProvider.GetDescription(itemIndex); if (string.IsNullOrEmpty(description)) { layout.SetMarkup(markup); } else { if (item == selection) { layout.SetMarkup(markup + " " + description); } else { layout.SetMarkup(markup + " <span foreground=\"darkgray\">" + description + "</span>"); } } int mw, mh; layout.GetPixelSize(out mw, out mh); if (mw > listWidth) { WidthRequest = listWidth = mw; win.WidthRequest = win.Allocation.Width + mw - width; win.QueueResize(); } string text = win.DataProvider.GetText(itemIndex); if ((!SelectionEnabled || item != selection) && !string.IsNullOrEmpty(text)) { int[] matchIndices = Match(CompletionString, text); if (matchIndices != null) { Pango.AttrList attrList = layout.Attributes ?? new Pango.AttrList(); for (int newSelection = 0; newSelection < matchIndices.Length; newSelection++) { int idx = matchIndices[newSelection]; Pango.AttrForeground fg = new Pango.AttrForeground(0, 0, ushort.MaxValue); fg.StartIndex = (uint)idx; fg.EndIndex = (uint)(idx + 1); attrList.Insert(fg); } layout.Attributes = attrList; } } Gdk.Pixbuf icon = win.DataProvider.GetIcon(itemIndex); int iconHeight, iconWidth; if (icon != null) { iconWidth = icon.Width; iconHeight = icon.Height; } else if (!Gtk.Icon.SizeLookup(Gtk.IconSize.Menu, out iconWidth, out iconHeight)) { iconHeight = iconWidth = 24; } int wi, he, typos, iypos; layout.GetPixelSize(out wi, out he); typos = he < rowHeight ? ypos + (rowHeight - he) / 2 : ypos; iypos = iconHeight < rowHeight ? ypos + (rowHeight - iconHeight) / 2 : ypos; if (item == selection) { if (SelectionEnabled) { window.DrawRectangle(this.Style.BaseGC(StateType.Selected), true, margin, ypos, lineWidth, he + padding); window.DrawLayout(this.Style.TextGC(StateType.Selected), xpos + iconWidth + 2, typos, layout); } else { window.DrawRectangle(this.Style.DarkGC(StateType.Prelight), false, margin, ypos, lineWidth - 1, he + padding - 1); window.DrawLayout(textGCNormal, xpos + iconWidth + 2, typos, layout); } } else { window.DrawLayout(textGCNormal, xpos + iconWidth + 2, typos, layout); } if (icon != null) { window.DrawPixbuf(fgGCNormal, icon, 0, 0, xpos, iypos, iconWidth, iconHeight, Gdk.RgbDither.None, 0, 0); } layout.SetMarkup(""); if (layout.Attributes != null) { layout.Attributes.Dispose(); layout.Attributes = null; } return(true); }); /* * int n = 0; * while (ypos < winHeight - margin && (page + n) < filteredItems.Count) { * * bool hasMarkup = win.DataProvider.HasMarkup (filteredItems[page + n]); * if (hasMarkup) { * layout.SetMarkup (win.DataProvider.GetMarkup (filteredItems[page + n]) ?? "<null>"); * } else { * layout.SetText (win.DataProvider.GetText (filteredItems[page + n]) ?? "<null>"); * } * string text = win.DataProvider.GetText (filteredItems[page + n]); * if ((!SelectionEnabled || page + n != selection) && !string.IsNullOrEmpty (text)) { * int[] matchIndices = Match (CompletionString, text); * if (matchIndices != null) { * Pango.AttrList attrList = layout.Attributes ?? new Pango.AttrList (); * for (int newSelection = 0; newSelection < matchIndices.Length; newSelection++) { * int idx = matchIndices[newSelection]; * Pango.AttrForeground fg = new Pango.AttrForeground (0, 0, ushort.MaxValue); * fg.StartIndex = (uint)idx; * fg.EndIndex = (uint)(idx + 1); * attrList.Insert (fg); * } * layout.Attributes = attrList; * } * } * * Gdk.Pixbuf icon = win.DataProvider.GetIcon (filteredItems[page + n]); * int iconHeight, iconWidth; * if (icon != null) { * iconWidth = icon.Width; * iconHeight = icon.Height; * } else if (!Gtk.Icon.SizeLookup (Gtk.IconSize.Menu, out iconWidth, out iconHeight)) { * iconHeight = iconWidth = 24; * } * * int wi, he, typos, iypos; * layout.GetPixelSize (out wi, out he); * typos = he < rowHeight ? ypos + (rowHeight - he) / 2 : ypos; * iypos = iconHeight < rowHeight ? ypos + (rowHeight - iconHeight) / 2 : ypos; * if (page + n == selection) { * if (SelectionEnabled) { * window.DrawRectangle (this.Style.BaseGC (StateType.Selected), true, margin, ypos, lineWidth, he + padding); * window.DrawLayout (this.Style.TextGC (StateType.Selected), xpos + iconWidth + 2, typos, layout); * } else { * window.DrawRectangle (this.Style.DarkGC (StateType.Prelight), false, margin, ypos, lineWidth - 1, he + padding - 1); * window.DrawLayout (this.Style.TextGC (StateType.Normal), xpos + iconWidth + 2, typos, layout); * } * } else * window.DrawLayout (this.Style.TextGC (StateType.Normal), xpos + iconWidth + 2, typos, layout); * if (icon != null) * window.DrawPixbuf (this.Style.ForegroundGC (StateType.Normal), icon, 0, 0, xpos, iypos, iconWidth, iconHeight, Gdk.RgbDither.None, 0, 0); * ypos += rowHeight; * n++; * if (hasMarkup) * layout.SetMarkup (string.Empty); * if (layout.Attributes != null) { * layout.Attributes.Dispose (); * layout.Attributes = null; * } * } */ return(true); }
protected override void Render (Gdk.Drawable drawable, Widget widget, Gdk.Rectangle background_area, Gdk.Rectangle cell_area, Gdk.Rectangle expose_area, CellRendererState flags) { if (source == null) { return; } view = widget as SourceView; bool path_selected = view != null && view.Selection.PathIsSelected (path); StateType state = RendererStateToWidgetState (widget, flags); RenderSelection (drawable, background_area, path_selected, state); int title_layout_width = 0, title_layout_height = 0; int count_layout_width = 0, count_layout_height = 0; int max_title_layout_width; bool hide_counts = source.Count <= 0; Pixbuf icon = SourceIconResolver.ResolveIcon (source, RowHeight); if (state == StateType.Insensitive) { // Code ported from gtk_cell_renderer_pixbuf_render() var icon_source = new IconSource () { Pixbuf = icon, Size = IconSize.SmallToolbar, SizeWildcarded = false }; icon = widget.Style.RenderIcon (icon_source, widget.Direction, state, (IconSize)(-1), widget, "SourceRowRenderer"); } FontDescription fd = widget.PangoContext.FontDescription.Copy (); fd.Weight = (ISource)ServiceManager.PlaybackController.NextSource == (ISource)source ? Pango.Weight.Bold : Pango.Weight.Normal; if (view != null && source == view.NewPlaylistSource) { fd.Style = Pango.Style.Italic; hide_counts = true; } Pango.Layout title_layout = new Pango.Layout (widget.PangoContext); Pango.Layout count_layout = null; if (!hide_counts) { count_layout = new Pango.Layout (widget.PangoContext); count_layout.FontDescription = fd; count_layout.SetMarkup (String.Format ("<span size=\"small\">{0}</span>", source.Count)); count_layout.GetPixelSize (out count_layout_width, out count_layout_height); } max_title_layout_width = cell_area.Width - (icon == null ? 0 : icon.Width) - count_layout_width - 10; if (!hide_counts && max_title_layout_width < 0) { hide_counts = true; } title_layout.FontDescription = fd; title_layout.Width = (int)(max_title_layout_width * Pango.Scale.PangoScale); title_layout.Ellipsize = EllipsizeMode.End; title_layout.SetText (source.Name); title_layout.GetPixelSize (out title_layout_width, out title_layout_height); Gdk.GC main_gc = widget.Style.TextGC (state); drawable.DrawLayout (main_gc, cell_area.X + (icon == null ? 0 : icon.Width) + 6, Middle (cell_area, title_layout_height), title_layout); if (icon != null) { drawable.DrawPixbuf (main_gc, icon, 0, 0, cell_area.X, Middle (cell_area, icon.Height), icon.Width, icon.Height, RgbDither.None, 0, 0); } if (hide_counts) { return; } Gdk.GC mod_gc = widget.Style.TextGC (state); if (state == StateType.Normal || (view != null && state == StateType.Prelight)) { Gdk.Color fgcolor = widget.Style.Base (state); Gdk.Color bgcolor = widget.Style.Text (state); mod_gc = new Gdk.GC (drawable); mod_gc.Copy (widget.Style.TextGC (state)); mod_gc.RgbFgColor = Hyena.Gui.GtkUtilities.ColorBlend (fgcolor, bgcolor); mod_gc.RgbBgColor = fgcolor; } drawable.DrawLayout (mod_gc, cell_area.X + cell_area.Width - count_layout_width - 2, Middle (cell_area, count_layout_height), count_layout); }
protected override void OnRender(Cairo.Context cr, Widget widget, Gdk.Rectangle background_area, Gdk.Rectangle cell_area, CellRendererState flags) { if (source == null || source is SourceManager.GroupSource) { return; } view = widget as SourceView; bool selected = view != null && view.Selection.IterIsSelected(iter); StateFlags state = RendererStateToWidgetState(widget, flags); RenderBackground(cr, background_area, selected, state); int title_layout_width = 0, title_layout_height = 0; int count_layout_width = 0, count_layout_height = 0; int max_title_layout_width; int img_padding = 6; int expander_icon_spacing = 3; int x = cell_area.X; bool np_etc = (source.Order + Depth * 100) < 40; if (!np_etc) { x += Depth * img_padding + (int)Xpad; } else { // Don't indent NowPlaying and Play Queue as much x += Math.Max(0, (int)Xpad - 2); } // Draw the expander if the source has children double exp_h = (cell_area.Height - 2.0 * Ypad) / 2.0; double exp_w = exp_h * 1.6; int y = Middle(cell_area, (int)exp_h); if (view != null && source.Children != null && source.Children.Count > 0) { var r = new Gdk.Rectangle(x, y, (int)exp_w, (int)exp_h); view.Theme.DrawArrow(cr, r, source.Expanded ? Math.PI / 2.0 : 0.0); } if (!np_etc) { x += (int)exp_w; x += 2; // a little spacing after the expander expander_right_x = x; } // Draw icon Pixbuf icon = SourceIconResolver.ResolveIcon(source, RowHeight); bool dispose_icon = false; if (state == StateFlags.Insensitive) { // Code ported from gtk_cell_renderer_pixbuf_render() var icon_source = new IconSource() { Pixbuf = icon, Size = IconSize.SmallToolbar, SizeWildcarded = false }; icon = widget.StyleContext.RenderIconPixbuf(icon_source, (IconSize)(-1)); dispose_icon = true; icon_source.Dispose(); } if (icon != null) { x += expander_icon_spacing; cr.Save(); Gdk.CairoHelper.SetSourcePixbuf(cr, icon, x, Middle(cell_area, icon.Height)); cr.Paint(); cr.Restore(); x += icon.Width; if (dispose_icon) { icon.Dispose(); } } // Setup font info for the title/count, and see if we should show the count bool hide_count = source.EnabledCount <= 0 || source.Properties.Get <bool> ("SourceView.HideCount"); FontDescription fd = widget.PangoContext.FontDescription.Copy(); fd.Weight = (ISource)ServiceManager.PlaybackController.NextSource == (ISource)source ? Pango.Weight.Bold : Pango.Weight.Normal; if (view != null && source == view.NewPlaylistSource) { fd.Style = Pango.Style.Italic; hide_count = true; } Pango.Layout title_layout = new Pango.Layout(widget.PangoContext); Pango.Layout count_layout = null; // If we have a count to draw, setup its fonts and see how wide it is to see if we have room if (!hide_count) { count_layout = new Pango.Layout(widget.PangoContext); count_layout.FontDescription = fd; count_layout.SetMarkup(String.Format("<span size=\"small\">{0}</span>", source.EnabledCount)); count_layout.GetPixelSize(out count_layout_width, out count_layout_height); } // Hide the count if the title has no space max_title_layout_width = cell_area.Width - x - count_layout_width;//(icon == null ? 0 : icon.Width) - count_layout_width - 10; if (!hide_count && max_title_layout_width <= 0) { hide_count = true; } // Draw the source Name title_layout.FontDescription = fd; title_layout.Width = (int)(max_title_layout_width * Pango.Scale.PangoScale); title_layout.Ellipsize = EllipsizeMode.End; title_layout.SetText(source.Name); title_layout.GetPixelSize(out title_layout_width, out title_layout_height); x += img_padding; widget.StyleContext.RenderLayout(cr, x, Middle(cell_area, title_layout_height), title_layout); title_layout.Dispose(); // Draw the count if (!hide_count) { if (view != null) { cr.SetSourceColor(state == StateFlags.Normal || (view != null && state == StateFlags.Prelight) ? view.Theme.TextMidColor : CairoExtensions.GdkRGBAToCairoColor(view.Theme.Widget.StyleContext.GetColor(state))); cr.MoveTo( cell_area.X + cell_area.Width - count_layout_width - 2, cell_area.Y + 0.5 + (double)(cell_area.Height - count_layout_height) / 2.0); Pango.CairoHelper.ShowLayout(cr, count_layout); } count_layout.Dispose(); } fd.Dispose(); }
protected override bool OnExposeEvent(Gdk.EventExpose args) { bool needsRefresh = false; using (var context = Gdk.CairoHelper.Create(args.Window)) { var scalef = GtkWorkarounds.GetScaleFactor(this); context.LineWidth = 1; var alloc = Allocation; int width = alloc.Width; int height = alloc.Height; context.Rectangle(args.Area.X, args.Area.Y, args.Area.Width, args.Area.Height); var backgroundColor = Styles.CodeCompletion.BackgroundColor.ToCairoColor(); var textColor = Styles.CodeCompletion.TextColor.ToCairoColor(); var categoryColor = Styles.CodeCompletion.CategoryColor.ToCairoColor(); context.SetSourceColor(backgroundColor); context.Fill(); int xpos = iconTextSpacing; int yPos = (int)-vadj.Value; //when there are no matches, display a message to indicate that the completion list is still handling input if (filteredItems.Count == 0) { context.Rectangle(0, yPos, width, height - yPos); context.SetSourceColor(backgroundColor); context.Stroke(); //TODO: David, line below is simplified noMatchLayout.SetText (DataProvider.ItemCount == 0 ? NoSuggestionsMsg : NoMatchesMsg); noMatchLayout.SetText(NoSuggestionsMsg); int lWidth, lHeight; noMatchLayout.GetPixelSize(out lWidth, out lHeight); context.SetSourceColor(textColor); context.MoveTo((width - lWidth) / 2, yPos + (height - lHeight - yPos) / 2 - lHeight / 2); Pango.CairoHelper.ShowLayout(context, noMatchLayout); return(false); } Iterate(true, ref yPos, delegate(int index, int itemidx, int ypos) { if (ypos >= height) { return(false); } if (ypos < -rowHeight) { return(true); } xpos = iconTextSpacing; var selected = index == SelectedItemIndex; bool drawIconAsSelected = SelectionEnabled && selected; var item = filteredItems [index]; string markup = GLib.Markup.EscapeText(item.DisplayText); string description = ""; //TODO: David DataProvider.GetDescription (item, drawIconAsSelected); if (string.IsNullOrEmpty(description)) { layout.SetMarkup(markup); } else { layout.SetMarkup(markup + " " + description); } string text = item.DisplayText; //TODO: David, where do we get HighlightedSpans? //if (!string.IsNullOrEmpty (text) && item.HighlightedSpans.Any ()) { // Pango.AttrList attrList = layout.Attributes ?? new Pango.AttrList (); // foreach (var span in item.HighlightedSpans) { // var bold = new AttrWeight (Weight.Bold); // bold.StartIndex = (uint)span.Start; // bold.EndIndex = (uint)span.End; // attrList.Insert (bold); // if (!selected) { // var highlightColor = (selected) ? Styles.CodeCompletion.SelectionHighlightColor : Styles.CodeCompletion.HighlightColor; // var fg = new AttrForeground ((ushort)(highlightColor.Red * ushort.MaxValue), (ushort)(highlightColor.Green * ushort.MaxValue), (ushort)(highlightColor.Blue * ushort.MaxValue)); // fg.StartIndex = (uint)span.Start; // fg.EndIndex = (uint)span.End; // attrList.Insert (fg); // } // } // layout.Attributes = attrList; //} Xwt.Drawing.Image icon = ImageService.GetIcon(GetIcon(item)); int iconHeight, iconWidth; if (icon != null) { if (drawIconAsSelected) { icon = icon.WithStyles("sel"); } iconWidth = (int)icon.Width; iconHeight = (int)icon.Height; } else if (!Gtk.Icon.SizeLookup(IconSize.Menu, out iconWidth, out iconHeight)) { iconHeight = iconWidth = 24; } int wi, he, typos, iypos; layout.GetPixelSize(out wi, out he); typos = he < rowHeight ? ypos + (int)Math.Ceiling((rowHeight - he) / 2.0) : ypos; if (scalef <= 1.0) { typos -= 1; // 1px up on non HiDPI } iypos = iconHeight < rowHeight ? ypos + (rowHeight - iconHeight) / 2 : ypos; if (selected) { var barStyle = SelectionEnabled ? Styles.CodeCompletion.SelectionBackgroundColor : Styles.CodeCompletion.SelectionBackgroundInactiveColor; context.SetSourceColor(barStyle.ToCairoColor()); if (SelectionEnabled) { context.Rectangle(0, ypos, Allocation.Width, rowHeight); context.Fill(); } else { context.LineWidth++; context.Rectangle(0.5, ypos + 0.5, Allocation.Width - 1, rowHeight - 1); context.Stroke(); context.LineWidth--; } } if (icon != null) { context.DrawImage(this, icon, xpos, iypos); xpos += iconTextSpacing; } context.SetSourceColor((drawIconAsSelected ? Styles.CodeCompletion.SelectionTextColor : Styles.CodeCompletion.TextColor).ToCairoColor()); var textXPos = xpos + iconWidth + 2; context.MoveTo(textXPos, typos); layout.Width = (int)((Allocation.Width - textXPos) * Pango.Scale.PangoScale); layout.Ellipsize = EllipsizeMode.End; Pango.CairoHelper.ShowLayout(context, layout); int textW, textH; layout.GetPixelSize(out textW, out textH); layout.Width = -1; layout.Ellipsize = EllipsizeMode.None; layout.SetMarkup(""); if (layout.Attributes != null) { layout.Attributes.Dispose(); layout.Attributes = null; } string rightText = ""; //TODO: David DataProvider.GetRightSideDescription (index, drawIconAsSelected); if (!string.IsNullOrEmpty(rightText)) { layout.SetMarkup(rightText); int w, h; layout.GetPixelSize(out w, out h); const int leftpadding = 8; const int rightpadding = 3; w += rightpadding; w = Math.Min(w, Allocation.Width - textXPos - textW - leftpadding); wi += w; typos = h < rowHeight ? ypos + (rowHeight - h) / 2 : ypos; if (scalef <= 1.0) { typos -= 1; // 1px up on non HiDPI } context.MoveTo(Allocation.Width - w, typos); layout.Width = (int)(w * Pango.Scale.PangoScale); layout.Ellipsize = EllipsizeMode.End; Pango.CairoHelper.ShowLayout(context, layout); layout.Width = -1; layout.Ellipsize = EllipsizeMode.None; } if (Math.Min(maxListWidth, wi + xpos + iconWidth + 2) > listWidth) { box.WidthRequest = listWidth = Math.Min(maxListWidth, wi + xpos + iconWidth + 2 + iconTextSpacing); needsRefresh = true; } else { //workaround for the vscrollbar display - the calculated width needs to be the width ofthe render region. if (Allocation.Width < listWidth) { if (listWidth - Allocation.Width < 30) { box.WidthRequest = listWidth + listWidth - Allocation.Width; needsRefresh = true; } } } return(true); }); if (needsRefresh) { QueueSpaceReservationStackRefresh(); } return(false); } }
// FIXME Cache the GCs? private void DrawCell (int thumbnail_num, Gdk.Rectangle area) { Gdk.Rectangle bounds = CellBounds (thumbnail_num); if (!bounds.Intersect (area, out area)) return; FSpot.IBrowsableItem photo = collection [thumbnail_num]; string thumbnail_path = FSpot.ThumbnailGenerator.ThumbnailPath (photo.DefaultVersionUri); FSpot.PixbufCache.CacheEntry entry = cache.Lookup (thumbnail_path); if (entry == null) cache.Request (thumbnail_path, thumbnail_num, ThumbnailWidth, ThumbnailHeight); else entry.Data = thumbnail_num; bool selected = selection.Contains (thumbnail_num); StateType cell_state = selected ? (HasFocus ? StateType.Selected : StateType.Active) : State; if (cell_state != State) Style.PaintBox (Style, BinWindow, cell_state, ShadowType.Out, area, this, "IconView", bounds.X, bounds.Y, bounds.Width - 1, bounds.Height - 1); Gdk.Rectangle focus = Gdk.Rectangle.Inflate (bounds, -3, -3); if (HasFocus && thumbnail_num == FocusCell) { Style.PaintFocus(Style, BinWindow, cell_state, area, this, null, focus.X, focus.Y, focus.Width, focus.Height); } Gdk.Rectangle region = Gdk.Rectangle.Zero; Gdk.Rectangle image_bounds = Gdk.Rectangle.Inflate (bounds, -cell_border_width, -cell_border_width); int expansion = ThrobExpansion (thumbnail_num, selected); Gdk.Pixbuf thumbnail = null; if (entry != null) thumbnail = entry.ShallowCopyPixbuf (); if (Gdk.Rectangle.Inflate (image_bounds, expansion + 1, expansion + 1).Intersect (area, out image_bounds) && thumbnail != null) { PixbufUtils.Fit (thumbnail, ThumbnailWidth, ThumbnailHeight, true, out region.Width, out region.Height); region.X = (int) (bounds.X + (bounds.Width - region.Width) / 2); region.Y = (int) bounds.Y + ThumbnailHeight - region.Height + cell_border_width; if (region.Width != thumbnail.Width && region.Height != thumbnail.Height) cache.Reload (entry, thumbnail_num, thumbnail.Width, thumbnail.Height); region = Gdk.Rectangle.Inflate (region, expansion, expansion); Pixbuf temp_thumbnail; region.Width = System.Math.Max (1, region.Width); region.Height = System.Math.Max (1, region.Height); if (region.Width != thumbnail.Width && region.Height != thumbnail.Height) { if (region.Width < thumbnail.Width && region.Height < thumbnail.Height) { /* temp_thumbnail = PixbufUtils.ScaleDown (thumbnail, region.Width, region.Height); */ temp_thumbnail = thumbnail.ScaleSimple (region.Width, region.Height, InterpType.Bilinear); lock (entry) { if (entry.Reload && expansion == 0 && !entry.IsDisposed) { entry.SetPixbufExtended (PixbufUtils.ShallowCopy (temp_thumbnail), false); entry.Reload = true; } } } else { temp_thumbnail = thumbnail.ScaleSimple (region.Width, region.Height, InterpType.Bilinear); } PixbufUtils.CopyThumbnailOptions (thumbnail, temp_thumbnail); } else temp_thumbnail = thumbnail; // FIXME There seems to be a rounding issue between the // scaled thumbnail sizes, we avoid this for now by using // the actual thumnail sizes here. region.Width = temp_thumbnail.Width; region.Height = temp_thumbnail.Height; Gdk.Rectangle draw = Gdk.Rectangle.Inflate (region, 1, 1); if (!temp_thumbnail.HasAlpha) Style.PaintShadow (Style, BinWindow, cell_state, ShadowType.Out, area, this, "IconView", draw.X, draw.Y, draw.Width, draw.Height); if (region.Intersect (area, out draw)) { temp_thumbnail.RenderToDrawable (BinWindow, Style.WhiteGC, draw.X - region.X, draw.Y - region.Y, draw.X, draw.Y, draw.Width, draw.Height, RgbDither.None, draw.X, draw.Y); } if (temp_thumbnail != thumbnail) { temp_thumbnail.Dispose (); } } if (thumbnail != null) { thumbnail.Dispose (); } Gdk.Rectangle layout_bounds = Gdk.Rectangle.Zero; if (DisplayDates) { string date; if (cell_width > 200) { date = photo.Time.ToLocalTime ().ToString (); } else { date = photo.Time.ToLocalTime ().ToShortDateString (); } Pango.Layout layout = (Pango.Layout)date_layouts [date]; if (layout == null) { layout = new Pango.Layout (this.PangoContext); layout.SetText (date); date_layouts [date] = layout; } layout.GetPixelSize (out layout_bounds.Width, out layout_bounds.Height); layout_bounds.Y = bounds.Y + bounds.Height - cell_border_width - layout_bounds.Height + tag_icon_vspacing; layout_bounds.X = bounds.X + (bounds.Width - layout_bounds.Width) / 2; if (DisplayTags) layout_bounds.Y -= tag_icon_size; if (DisplayFilenames) { Pango.FontMetrics metrics = this.PangoContext.GetMetrics (this.Style.FontDescription, Pango.Language.FromString ("en_US")); layout_bounds.Y -= PangoPixels (metrics.Ascent + metrics.Descent); } if (layout_bounds.Intersect (area, out region)) { Style.PaintLayout (Style, BinWindow, cell_state, true, area, this, "IconView", layout_bounds.X, layout_bounds.Y, layout); } } if (DisplayFilenames) { string filename = System.IO.Path.GetFileName (photo.DefaultVersionUri.LocalPath); Pango.Layout layout = new Pango.Layout (this.PangoContext); layout.SetText (filename); layout.GetPixelSize (out layout_bounds.Width, out layout_bounds.Height); layout_bounds.Y = bounds.Y + bounds.Height - cell_border_width - layout_bounds.Height + tag_icon_vspacing; layout_bounds.X = bounds.X + (bounds.Width - layout_bounds.Width) / 2; if (DisplayTags) layout_bounds.Y -= tag_icon_size; if (layout_bounds.Intersect (area, out region)) { Style.PaintLayout (Style, BinWindow, cell_state, true, area, this, "IconView", layout_bounds.X, layout_bounds.Y, layout); } } if (DisplayTags) { Tag [] tags = photo.Tags; Gdk.Rectangle tag_bounds; tag_bounds.X = bounds.X + (bounds.Width + tag_icon_hspacing - tags.Length * (tag_icon_size + tag_icon_hspacing)) / 2; tag_bounds.Y = bounds.Y + bounds.Height - cell_border_width - tag_icon_size + tag_icon_vspacing; tag_bounds.Width = tag_icon_size; tag_bounds.Height = tag_icon_size; foreach (Tag t in tags) { if (t == null) continue; Pixbuf icon = t.Icon; Tag tag_iter = t.Category; while (icon == null && tag_iter != Core.Database.Tags.RootCategory && tag_iter != null) { icon = tag_iter.Icon; tag_iter = tag_iter.Category; } if (icon == null) continue; if (tag_bounds.Intersect (area, out region)) { Pixbuf scaled_icon; if (icon.Width == tag_bounds.Width) { scaled_icon = icon; } else { scaled_icon = icon.ScaleSimple (tag_bounds.Width, tag_bounds.Height, InterpType.Bilinear); } scaled_icon.RenderToDrawable (BinWindow, Style.WhiteGC, region.X - tag_bounds.X, region.Y - tag_bounds.Y, region.X, region.Y, region.Width, region.Height, RgbDither.None, region.X, region.Y); if (scaled_icon != icon) { scaled_icon.Dispose (); } } tag_bounds.X += tag_bounds.Width + tag_icon_hspacing; } } }
//FIXME: we could use the expose event's clipbox to make the drawing more efficient void DrawList(Gdk.EventExpose args) { var window = args.Window; int winWidth, winHeight; window.GetSize(out winWidth, out winHeight); int ypos = margin; int lineWidth = winWidth - margin * 2; int xpos = margin + padding; //avoid recreating the GC objects that we use multiple times var textGCNormal = this.Style.TextGC(StateType.Normal); var fgGCNormal = this.Style.ForegroundGC(StateType.Normal); int n = 0; n = (int)(vadj.Value / rowHeight); while (ypos < winHeight - margin && n < win.DataProvider.Count) { bool hasMarkup = false; IMarkupListDataProvider <T> markupListDataProvider = win.DataProvider as IMarkupListDataProvider <T>; if (markupListDataProvider != null) { if (markupListDataProvider.HasMarkup(n)) { layout.SetMarkup(markupListDataProvider.GetMarkup(n) ?? "<null>"); hasMarkup = true; } } if (!hasMarkup) { layout.SetText(win.DataProvider.GetText(n) ?? "<null>"); } Gdk.Pixbuf icon = win.DataProvider.GetIcon(n); int iconHeight, iconWidth; if (icon != null) { iconWidth = icon.Width; iconHeight = icon.Height; } else if (!Gtk.Icon.SizeLookup(Gtk.IconSize.Menu, out iconWidth, out iconHeight)) { iconHeight = iconWidth = 24; } int wi, he, typos, iypos; layout.GetPixelSize(out wi, out he); typos = he < rowHeight ? ypos + (rowHeight - he) / 2 : ypos; iypos = iconHeight < rowHeight ? ypos + (rowHeight - iconHeight) / 2 : ypos; if (n == selection) { if (!disableSelection) { args.Window.DrawRectangle(this.Style.BaseGC(StateType.Selected), true, margin, ypos, lineWidth, he + padding); window.DrawLayout(this.Style.TextGC(StateType.Selected), xpos + iconWidth + 2, typos, layout); } else { window.DrawRectangle(this.Style.BaseGC(StateType.Selected), false, margin, ypos, lineWidth, he + padding); window.DrawLayout(textGCNormal, xpos + iconWidth + 2, typos, layout); } } else { window.DrawLayout(textGCNormal, xpos + iconWidth + 2, typos, layout); } if (icon != null) { window.DrawPixbuf(fgGCNormal, icon, 0, 0, xpos, iypos, iconWidth, iconHeight, Gdk.RgbDither.None, 0, 0); } ypos += rowHeight; n++; //reset the markup or it carries over to the next SetText if (hasMarkup) { layout.SetMarkup(string.Empty); } } }
protected override void Render (Gdk.Drawable drawable, Widget widget, Gdk.Rectangle background_area, Gdk.Rectangle cell_area, Gdk.Rectangle expose_area, CellRendererState flags) { if (source == null || source is SourceManager.GroupSource) { return; } view = widget as SourceView; bool selected = view != null && view.Selection.IterIsSelected (iter); StateType state = RendererStateToWidgetState (widget, flags); RenderSelection (drawable, background_area, selected, state); int title_layout_width = 0, title_layout_height = 0; int count_layout_width = 0, count_layout_height = 0; int max_title_layout_width; int img_padding = 6; int expander_icon_spacing = 3; int x = cell_area.X; bool np_etc = (source.Order + Depth * 100) < 40; if (!np_etc) { x += Depth * img_padding + (int)Xpad; } else { // Don't indent NowPlaying and Play Queue as much x += Math.Max (0, (int)Xpad - 2); } Gdk.GC main_gc = widget.Style.TextGC (state); // Draw the expander if the source has children double exp_h = (cell_area.Height - 2.0*Ypad) / 3.2; double exp_w = exp_h * 1.6; if (view != null && view.Cr != null && source.Children != null && source.Children.Count > 0) { var r = new Gdk.Rectangle (x, cell_area.Y + (int)((cell_area.Height - exp_h) / 2.0), (int)exp_w, (int)exp_h); view.Theme.DrawArrow (view.Cr, r, source.Expanded ? Math.PI/2.0 : 0.0); } if (!np_etc) { x += (int) exp_w; x += 2; // a little spacing after the expander expander_right_x = x; } // Draw icon Pixbuf icon = SourceIconResolver.ResolveIcon (source, RowHeight); bool dispose_icon = false; if (state == StateType.Insensitive) { // Code ported from gtk_cell_renderer_pixbuf_render() var icon_source = new IconSource () { Pixbuf = icon, Size = IconSize.SmallToolbar, SizeWildcarded = false }; icon = widget.Style.RenderIcon (icon_source, widget.Direction, state, (IconSize)(-1), widget, "SourceRowRenderer"); dispose_icon = true; icon_source.Dispose (); } if (icon != null) { x += expander_icon_spacing; drawable.DrawPixbuf (main_gc, icon, 0, 0, x, Middle (cell_area, icon.Height), icon.Width, icon.Height, RgbDither.None, 0, 0); x += icon.Width; if (dispose_icon) { icon.Dispose (); } } // Setup font info for the title/count, and see if we should show the count bool hide_count = source.EnabledCount <= 0 || source.Properties.Get<bool> ("SourceView.HideCount"); FontDescription fd = widget.PangoContext.FontDescription.Copy (); fd.Weight = (ISource)ServiceManager.PlaybackController.NextSource == (ISource)source ? Pango.Weight.Bold : Pango.Weight.Normal; if (view != null && source == view.NewPlaylistSource) { fd.Style = Pango.Style.Italic; hide_count = true; } Pango.Layout title_layout = new Pango.Layout (widget.PangoContext); Pango.Layout count_layout = null; // If we have a count to draw, setup its fonts and see how wide it is to see if we have room if (!hide_count) { count_layout = new Pango.Layout (widget.PangoContext); count_layout.FontDescription = fd; count_layout.SetMarkup (String.Format ("<span size=\"small\">{0}</span>", source.EnabledCount)); count_layout.GetPixelSize (out count_layout_width, out count_layout_height); } // Hide the count if the title has no space max_title_layout_width = cell_area.Width - x - count_layout_width;//(icon == null ? 0 : icon.Width) - count_layout_width - 10; if (!hide_count && max_title_layout_width <= 0) { hide_count = true; } // Draw the source Name title_layout.FontDescription = fd; title_layout.Width = (int)(max_title_layout_width * Pango.Scale.PangoScale); title_layout.Ellipsize = EllipsizeMode.End; title_layout.SetText (source.Name); title_layout.GetPixelSize (out title_layout_width, out title_layout_height); x += img_padding; drawable.DrawLayout (main_gc, x, Middle (cell_area, title_layout_height), title_layout); title_layout.Dispose (); // Draw the count if (!hide_count) { if (view != null && view.Cr != null) { view.Cr.Color = state == StateType.Normal || (view != null && state == StateType.Prelight) ? view.Theme.TextMidColor : view.Theme.Colors.GetWidgetColor (GtkColorClass.Text, state); view.Cr.MoveTo ( cell_area.X + cell_area.Width - count_layout_width - 2, cell_area.Y + 0.5 + (double)(cell_area.Height - count_layout_height) / 2.0); PangoCairoHelper.ShowLayout (view.Cr, count_layout); } count_layout.Dispose (); } fd.Dispose (); }
public void draw(Gdk.Window win, Gdk.Color terr, Gdk.Color textcolor, Pango.Context pango_context) { Gdk.GC textcoloring = new Gdk.GC(win); textcoloring.RgbFgColor = textcolor; int carriedUnits = 0; string extraLabel = ""; GraphicsStorage store = GraphicsStorage.GetInstance(); int cenTerrX = MapTerritory.centerX; int cenTerrY = MapTerritory.centerY; /* Show flag */ Gdk.Pixbuf flag = store.AppropriateFlag(owner.CountryID); if (flag != null && owner.Active) win.DrawPixbuf(textcoloring, flag, 0, 0, cenTerrX, cenTerrY, flag.Width, flag.Height, RgbDither.Normal, 1, 1); /* Draw the map */ MapTerritory.draw(win, terr, textcolor); /* Show radiation if destroyed */ if (destroyed) win.DrawPixbuf(textcoloring, store.Radiation, 0, 0, cenTerrX, cenTerrY, store.Radiation.Width, store.Radiation.Height, RgbDither.Normal, 1, 1); /* Determine personnel carrier status */ foreach(TacticalUnit joe in units) carriedUnits += joe.UnitsAboardCount; if (carriedUnits > 0) extraLabel = "(" + carriedUnits + ")"; /* Draw the first N units staggered, then use a label to show further #'s */ for (int offset=0; offset < units.Count && offset < 3; offset++) { ((TacticalUnit)units[offset]).draw(win, offset*5); } /* Label */ if (units.Count > 1 || carriedUnits > 0) { Pango.Layout label = new Pango.Layout (pango_context); label.Wrap = Pango.WrapMode.Word; label.FontDescription = FontDescription.FromString ("Tahoma 8"); label.SetMarkup ( units.Count.ToString() + extraLabel ); int szX, szY; label.GetPixelSize(out szX, out szY); /*Redraw*/ // win.InvalidateRect(new Gdk.Rectangle(MapTerritory.centerX, MapTerritory.centerY, szX, szY), true); win.DrawLayout (textcoloring, MapTerritory.centerX, MapTerritory.centerY, label); } }
protected override bool OnExposeEvent(Gdk.EventExpose args) { using (var context = Gdk.CairoHelper.Create(args.Window)) { var scalef = GtkWorkarounds.GetScaleFactor(this); context.LineWidth = 1; var alloc = Allocation; int width = alloc.Width; int height = alloc.Height; context.Rectangle(args.Area.X, args.Area.Y, args.Area.Width, args.Area.Height); var backgroundColor = Styles.CodeCompletion.BackgroundColor.ToCairoColor(); var textColor = Styles.CodeCompletion.TextColor.ToCairoColor(); var categoryColor = Styles.CodeCompletion.CategoryColor.ToCairoColor(); context.SetSourceColor(backgroundColor); context.Fill(); int xpos = iconTextSpacing; int yPos = (int)-vadj.Value; //when there are no matches, display a message to indicate that the completion list is still handling input if (filteredItems.Count == 0) { context.Rectangle(0, yPos, width, height - yPos); context.SetSourceColor(backgroundColor); context.Stroke(); noMatchLayout.SetText(DataProvider.ItemCount == 0 ? NoSuggestionsMsg : NoMatchesMsg); int lWidth, lHeight; noMatchLayout.GetPixelSize(out lWidth, out lHeight); context.SetSourceColor(textColor); context.MoveTo((width - lWidth) / 2, yPos + (height - lHeight - yPos) / 2 - lHeight / 2); Pango.CairoHelper.ShowLayout(context, noMatchLayout); return(false); } Iterate(true, ref yPos, delegate(CategorizedCompletionItems category, int ypos) { if (ypos >= height) { return; } if (ypos < -rowHeight) { return; } // window.DrawRectangle (this.Style.BackgroundGC (StateType.Insensitive), true, 0, yPos, width, rowHeight); int x = 2; if (category.CompletionCategory != null && !string.IsNullOrEmpty(category.CompletionCategory.Icon)) { var icon = ImageService.GetIcon(category.CompletionCategory.Icon, IconSize.Menu); context.DrawImage(this, icon, 0, ypos); x = (int)icon.Width + 4; } context.Rectangle(0, ypos, Allocation.Width, rowHeight); context.SetSourceColor(backgroundColor); context.Fill(); // layout.SetMarkup ("<span weight='bold' foreground='#AAAAAA'>" + (category.CompletionCategory != null ? category.CompletionCategory.DisplayText : "Uncategorized") + "</span>"); // window.DrawLayout (textGCInsensitive, x - 1, ypos + 1 + (rowHeight - py) / 2, layout); // layout.SetMarkup ("<span weight='bold'>" + (category.CompletionCategory != null ? category.CompletionCategory.DisplayText : "Uncategorized") + "</span>"); categoryLayout.SetMarkup((category.CompletionCategory != null ? category.CompletionCategory.DisplayText : "Uncategorized")); int px, py; categoryLayout.GetPixelSize(out px, out py); context.MoveTo(x, ypos + (rowHeight - py) / 2); context.SetSourceColor(categoryColor); Pango.CairoHelper.ShowLayout(context, categoryLayout); }, delegate(CategorizedCompletionItems curCategory, int item, int itemidx, int ypos) { if (ypos >= height) { return(false); } if (ypos < -rowHeight) { return(true); } const int categoryModeItemIndenting = 0; if (InCategoryMode && curCategory != null && curCategory.CompletionCategory != null) { xpos = iconTextSpacing + categoryModeItemIndenting; } else { xpos = iconTextSpacing; } bool drawIconAsSelected = SelectionEnabled && item == SelectedItemIndex; string markup = DataProvider.HasMarkup(item) ? (DataProvider.GetMarkup(item) ?? "<null>") : GLib.Markup.EscapeText(DataProvider.GetText(item) ?? "<null>"); string description = DataProvider.GetDescription(item, drawIconAsSelected); if (string.IsNullOrEmpty(description)) { layout.SetMarkup(markup); } else { layout.SetMarkup(markup + " " + description); } string text = DataProvider.GetText(item); if (!string.IsNullOrEmpty(text)) { int [] matchIndices = DataProvider.GetHighlightedTextIndices(item); if (matchIndices != null) { Pango.AttrList attrList = layout.Attributes ?? new Pango.AttrList(); for (int newSelection = 0; newSelection < matchIndices.Length; newSelection++) { int idx = matchIndices [newSelection]; var bold = new AttrWeight(Weight.Bold); bold.StartIndex = (uint)idx; bold.EndIndex = (uint)(idx + 1); attrList.Insert(bold); if (item != SelectedItemIndex) { var highlightColor = (item == SelectedItemIndex) ? Styles.CodeCompletion.SelectionHighlightColor : Styles.CodeCompletion.HighlightColor; var fg = new AttrForeground((ushort)(highlightColor.Red * ushort.MaxValue), (ushort)(highlightColor.Green * ushort.MaxValue), (ushort)(highlightColor.Blue * ushort.MaxValue)); fg.StartIndex = (uint)idx; fg.EndIndex = (uint)(idx + 1); attrList.Insert(fg); } } layout.Attributes = attrList; } } Xwt.Drawing.Image icon = DataProvider.GetIcon(item); int iconHeight, iconWidth; if (icon != null) { if (drawIconAsSelected) { icon = icon.WithStyles("sel"); } iconWidth = (int)icon.Width; iconHeight = (int)icon.Height; } else if (!Gtk.Icon.SizeLookup(IconSize.Menu, out iconWidth, out iconHeight)) { iconHeight = iconWidth = 24; } int wi, he, typos, iypos; layout.GetPixelSize(out wi, out he); typos = he < rowHeight ? ypos + (int)Math.Ceiling((rowHeight - he) / 2.0) : ypos; if (scalef <= 1.0) { typos -= 1; // 1px up on non HiDPI } iypos = iconHeight < rowHeight ? ypos + (rowHeight - iconHeight) / 2 : ypos; if (item == SelectedItemIndex) { var barStyle = SelectionEnabled ? Styles.CodeCompletion.SelectionBackgroundColor : Styles.CodeCompletion.SelectionBackgroundInactiveColor; context.SetSourceColor(barStyle.ToCairoColor()); if (SelectionEnabled) { context.Rectangle(0, ypos, Allocation.Width, rowHeight); context.Fill(); } else { context.LineWidth++; context.Rectangle(0.5, ypos + 0.5, Allocation.Width - 1, rowHeight - 1); context.Stroke(); context.LineWidth--; } } if (icon != null) { context.DrawImage(this, icon, xpos, iypos); xpos += iconTextSpacing; } context.SetSourceColor((drawIconAsSelected ? Styles.CodeCompletion.SelectionTextColor : Styles.CodeCompletion.TextColor).ToCairoColor()); var textXPos = xpos + iconWidth + 2; context.MoveTo(textXPos, typos); layout.Width = (int)((Allocation.Width - textXPos) * Pango.Scale.PangoScale); layout.Ellipsize = EllipsizeMode.End; Pango.CairoHelper.ShowLayout(context, layout); int textW, textH; layout.GetPixelSize(out textW, out textH); layout.Width = -1; layout.Ellipsize = EllipsizeMode.None; layout.SetMarkup(""); if (layout.Attributes != null) { layout.Attributes.Dispose(); layout.Attributes = null; } string rightText = DataProvider.GetRightSideDescription(item, drawIconAsSelected); if (!string.IsNullOrEmpty(rightText)) { layout.SetMarkup(rightText); int w, h; layout.GetPixelSize(out w, out h); const int leftpadding = 8; const int rightpadding = 3; w += rightpadding; w = Math.Min(w, Allocation.Width - textXPos - textW - leftpadding); wi += w; typos = h < rowHeight ? ypos + (rowHeight - h) / 2 : ypos; if (scalef <= 1.0) { typos -= 1; // 1px up on non HiDPI } context.MoveTo(Allocation.Width - w, typos); layout.Width = (int)(w * Pango.Scale.PangoScale); layout.Ellipsize = EllipsizeMode.End; Pango.CairoHelper.ShowLayout(context, layout); layout.Width = -1; layout.Ellipsize = EllipsizeMode.None; } if (Math.Min(maxListWidth, wi + xpos + iconWidth + 2) > listWidth) { WidthRequest = listWidth = Math.Min(maxListWidth, wi + xpos + iconWidth + 2 + iconTextSpacing); win.ResetSizes(); } else { //workaround for the vscrollbar display - the calculated width needs to be the width ofthe render region. if (Allocation.Width < listWidth) { if (listWidth - Allocation.Width < 30) { WidthRequest = listWidth + listWidth - Allocation.Width; win.ResetSizes(); } } } return(true); }); return(false); } }
void MeasureLine (IReadonlyTextDocument document, int lineNumber, ref int x, ref int y) { using (var drawingLayout = new Pango.Layout (this.PangoContext)) { drawingLayout.FontDescription = fontDescription; var line = document.GetLine (lineNumber); var indent = line.GetIndentation (document); var curLineIndent = CalcIndentLength(indent); if (line.Length == curLineIndent) { y += lineHeight; return; } if (this.indentLength < 0 || this.indentLength > curLineIndent) this.indentLength = curLineIndent; drawingLayout.SetText (document.GetTextAt (line)); int w, h; drawingLayout.GetPixelSize (out w, out h); x = Math.Max (x, w); y += lineHeight; } }