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 ();
}