private void BuildViews () { source_box = new VBox (); views_pane = new HPaned (); PersistentPaneController.Control (views_pane, SourceViewWidth); view_container = new ViewContainer (); source_view = new SourceView (); composite_view = new CompositeTrackSourceContents (); Container source_scroll; if (PlatformDetection.IsMeeGo) { source_scroll = new Gtk.ScrolledWindow () { HscrollbarPolicy = PolicyType.Never, VscrollbarPolicy = PolicyType.Automatic, ShadowType = ShadowType.None }; source_scroll.Add (source_view); var color = new Gdk.Color ((byte)0xe6, (byte)0xe6, (byte)0xe6); Gdk.Colormap.System.AllocColor (ref color, true, true); source_view.ModifyBase (StateType.Normal, color); } else { Hyena.Widgets.ScrolledWindow window; if (ApplicationContext.CommandLine.Contains ("smooth-scroll")) { window = new Hyena.Widgets.SmoothScrolledWindow (); } else { window = new Hyena.Widgets.ScrolledWindow (); } window.AddWithFrame (source_view); source_scroll = window; } composite_view.TrackView.HeaderVisible = false; view_container.Content = composite_view; source_box.PackStart (source_scroll, true, true, 0); source_box.PackStart (new UserJobTileHost (), false, false, 0); UpdateCoverArtDisplay (); source_view.SetSizeRequest (125, -1); view_container.SetSizeRequest (425, -1); views_pane.Pack1 (source_box, false, false); views_pane.Pack2 (view_container, true, false); source_box.ShowAll (); view_container.Show (); views_pane.Show (); primary_vbox.PackStart (views_pane, true, true, 0); }
public SourceSwitcherEntry (SourceView view) { this.view = view; HideAfterTimeout = false; // FIXME not sure if it's possible to do auto-complete w/o a Model /*var completion = new EntryCompletion () { //InlineSelection = true, //InlineCompletion = true, PopupCompletion = true, MatchFunc = (c, key, iter) => { //Console.WriteLine ("MatchFunc called! for key {0}", key); return true; }, PopupSingleMatch = true, MinimumKeyLength = 1 }; var store = new ListStore (typeof (string)); completion.TextColumn = 0; completion.Model = store; completion.PopupCompletion = true; completion.PopupSingleMatch = true; Entry.Completion = completion; completion.ActionActivated += (o2, a) => { Console.WriteLine ("completion.ActionActivated"); try { SwitchSource (SourceSwitcherMatches (Text).Skip (a.Index).FirstOrDefault ()); } catch {} };*/ Changed += delegate { //store.Clear (); //completion.Complete (); if (hide_timeout_id != 0) { ServiceStack.Application.IdleTimeoutRemove (hide_timeout_id); hide_timeout_id = 0; } if (Text.Length > 0) { // If there is only one source that matches, switch to it var list = SourceSwitcherMatches (Text).ToList (); if (list.Count == 1) { SwitchSource (list[0]); // Hide only after a timeout, helps to capture extra entered chars if we switch before the user expects hide_timeout_id = ServiceStack.Application.RunTimeout (1000, delegate { Hide (); return false; }); } else { /*foreach (var src in list) { store.AppendValues (src.Name); }*/ } } }; Entry.Activated += delegate { try { var src = SourceSwitcherMatches (Text).FirstOrDefault (); SwitchSource (src); } catch {} }; Position (view.GdkWindow); HasFocus = true; Show (); }
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 (); }
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 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); }
public SourceSwitcherEntry(SourceView view) { this.view = view; HideAfterTimeout = false; // FIXME not sure if it's possible to do auto-complete w/o a Model /*var completion = new EntryCompletion () { * //InlineSelection = true, * //InlineCompletion = true, * PopupCompletion = true, * MatchFunc = (c, key, iter) => { * //Console.WriteLine ("MatchFunc called! for key {0}", key); * return true; * }, * PopupSingleMatch = true, * MinimumKeyLength = 1 * }; * * var store = new ListStore (typeof (string)); * completion.TextColumn = 0; * completion.Model = store; * completion.PopupCompletion = true; * completion.PopupSingleMatch = true; * * Entry.Completion = completion; * completion.ActionActivated += (o2, a) => { * Console.WriteLine ("completion.ActionActivated"); * try { * SwitchSource (SourceSwitcherMatches (Text).Skip (a.Index).FirstOrDefault ()); * } catch {} * };*/ Changed += delegate { //store.Clear (); //completion.Complete (); if (hide_timeout_id != 0) { ServiceStack.Application.IdleTimeoutRemove(hide_timeout_id); hide_timeout_id = 0; } if (Text.Length > 0) { // If there is only one source that matches, switch to it var list = SourceSwitcherMatches(Text).ToList(); if (list.Count == 1) { SwitchSource(list[0]); // Hide only after a timeout, helps to capture extra entered chars if we switch before the user expects hide_timeout_id = ServiceStack.Application.RunTimeout(1000, delegate { Hide(); return(false); }); } else { /*foreach (var src in list) { * store.AppendValues (src.Name); * }*/ } } }; Entry.Activated += delegate { try { var src = SourceSwitcherMatches(Text).FirstOrDefault(); SwitchSource(src); } catch {} }; Position(view.GdkWindow); HasFocus = true; Show(); }
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 (); }
private void BuildViews() { source_box = new VBox (); views_pane = new HPaned (); PersistentPaneController.Control (views_pane, SourceViewWidth); view_container = new ViewContainer (); source_view = new SourceView (); composite_view = new CompositeTrackSourceContents (); Container source_scroll; Hyena.Widgets.ScrolledWindow window; if (ApplicationContext.CommandLine.Contains ("smooth-scroll")) { window = new Hyena.Widgets.SmoothScrolledWindow (); } else { window = new Hyena.Widgets.ScrolledWindow (); } window.AddWithFrame (source_view); source_scroll = window; composite_view.TrackView.HeaderVisible = false; view_container.Content = composite_view; source_box.PackStart (source_scroll, true, true, 0); source_box.PackStart (new UserJobTileHost (), false, false, 0); UpdateCoverArtDisplay (); source_view.SetSizeRequest (125, -1); view_container.SetSizeRequest (425, -1); views_pane.Pack1 (source_box, false, false); views_pane.Pack2 (view_container, true, false); source_box.ShowAll (); view_container.Show (); views_pane.Show (); primary_vbox.PackStart (views_pane, true, true, 0); }