[banshee] [ThickClient] Make the seek slider resizable (bgo#537580)



commit c2288fbb66667b8f66ce0d5ab83fc5f72865f5a0
Author: Gabriel Burt <gabriel burt gmail com>
Date:   Sun Sep 5 07:23:26 2010 -0500

    [ThickClient] Make the seek slider resizable (bgo#537580)

 src/Clients/Nereid/Nereid/PlayerInterface.cs       |   22 ++++--
 .../Banshee.Gui.Widgets/ConnectedSeekSlider.cs     |   75 +++++++++++++++++++-
 2 files changed, 88 insertions(+), 9 deletions(-)
---
diff --git a/src/Clients/Nereid/Nereid/PlayerInterface.cs b/src/Clients/Nereid/Nereid/PlayerInterface.cs
index 3175b3e..676b61f 100644
--- a/src/Clients/Nereid/Nereid/PlayerInterface.cs
+++ b/src/Clients/Nereid/Nereid/PlayerInterface.cs
@@ -94,16 +94,12 @@ namespace Nereid
         {
         }
 
-        private int? original_seek_width;
         private void SetSimple (bool simple)
         {
             main_menu.Visible =
             source_box.Visible =
             footer_toolbar.Visible =
             track_info_container.Visible = !simple;
-
-            original_seek_width = original_seek_width ?? seek_slider.SeekSlider.WidthRequest;
-            seek_slider.SeekSlider.WidthRequest = original_seek_width.Value + (simple ? 100 : 0);
         }
 
         public PlayerInterface () : base (Catalog.GetString ("Banshee Media Player"), "player_window", 1024, 700)
@@ -214,8 +210,12 @@ namespace Nereid
             next_button.Show ();
             ActionService.PopulateToolbarPlaceholder (header_toolbar, "/HeaderToolbar/NextArrowButton", next_button);
 
-            seek_slider = new ConnectedSeekSlider ();
-            seek_slider.Show ();
+            seek_slider = new ConnectedSeekSlider () { Resizable = ShowSeekSliderResizer.Get () };
+            seek_slider.SeekSlider.WidthRequest = SeekSliderWidth.Get ();
+            seek_slider.SeekSlider.SizeAllocated += (o, a) => {
+                SeekSliderWidth.Set (seek_slider.SeekSlider.Allocation.Width);
+            };
+            seek_slider.ShowAll ();
             ActionService.PopulateToolbarPlaceholder (header_toolbar, "/HeaderToolbar/SeekSlider", seek_slider);
 
             var track_info_display = new ClassicTrackInfoDisplay ();
@@ -770,6 +770,16 @@ namespace Nereid
             "Show cover art below source view if available"
         );
 
+        private static readonly SchemaEntry<bool> ShowSeekSliderResizer = new SchemaEntry<bool> (
+            "player_window", "show_seek_slider_resizer",
+            true, "Show seek slider resize grip", ""
+        );
+
+        private static readonly SchemaEntry<int> SeekSliderWidth = new SchemaEntry<int> (
+            "player_window", "seek_slider_width",
+            175, "Width of seek slider in px", ""
+        );
+
 #endregion
 
         IDBusExportable IDBusExportable.Parent {
diff --git a/src/Core/Banshee.ThickClient/Banshee.Gui.Widgets/ConnectedSeekSlider.cs b/src/Core/Banshee.ThickClient/Banshee.Gui.Widgets/ConnectedSeekSlider.cs
index d0a9766..852ff5a 100644
--- a/src/Core/Banshee.ThickClient/Banshee.Gui.Widgets/ConnectedSeekSlider.cs
+++ b/src/Core/Banshee.ThickClient/Banshee.Gui.Widgets/ConnectedSeekSlider.cs
@@ -45,6 +45,7 @@ namespace Banshee.Gui.Widgets
         private SeekSlider seek_slider;
         private StreamPositionLabel stream_position_label;
         private Box box;
+        private GrabHandle grabber;
 
         public ConnectedSeekSlider () : this (SeekSliderLayout.Vertical)
         {
@@ -64,6 +65,7 @@ namespace Banshee.Gui.Widgets
                 PlayerEvent.StateChange);
 
             ServiceManager.PlayerEngine.TrackIntercept += OnTrackIntercept;
+            SizeAllocated += delegate { QueueDraw (); };
 
             seek_slider.SeekRequested += OnSeekRequested;
 
@@ -97,6 +99,7 @@ namespace Banshee.Gui.Widgets
 
         private void BuildSeekSlider (SeekSliderLayout layout)
         {
+            var hbox = new HBox () { Spacing = 2 };
             seek_slider = new SeekSlider ();
             stream_position_label = new StreamPositionLabel (seek_slider);
 
@@ -108,14 +111,80 @@ namespace Banshee.Gui.Widgets
                 box = new VBox ();
             }
 
-            seek_slider.SetSizeRequest (125, -1);
+            seek_slider.SetSizeRequest (175, -1);
 
             box.PackStart (seek_slider, true, true, 0);
             box.PackStart (stream_position_label, false, false, 0);
 
-            box.ShowAll ();
+            hbox.PackStart (box, true, true, 0);
 
-            Add (box);
+            grabber = new GrabHandle (5, 28);
+            grabber.MotionNotifyEvent += (o, a) => {
+                var x = a.Event.X;
+                var w = Math.Min (1024, Math.Max (125, seek_slider.WidthRequest + x));
+                seek_slider.WidthRequest = (int)w;
+            };
+
+            hbox.PackStart (grabber, true, true, 0);
+            hbox.ShowAll ();
+            Resizable = false;
+
+            Add (hbox);
+        }
+
+        public bool Resizable {
+            get { return grabber.Visible; }
+            set {
+                grabber.Visible = value;
+                // grabber is 5 + 2 spacing, do reduce right padding to 3
+                RightPadding = value ? (uint)3 : (uint)10;
+            }
+        }
+
+        private class GrabHandle : EventBox
+        {
+            Gtk.DrawingArea da;
+
+            public GrabHandle (int w, int h)
+            {
+                da = new DrawingArea ();
+                da.SetSizeRequest (w, h);
+                Orientation = Gtk.Orientation.Vertical;
+
+                Child = da;
+                ShowAll ();
+
+                ButtonPressEvent += (o, a) => Dragging = true;
+                ButtonReleaseEvent += (o, a) => Dragging = false;
+                EnterNotifyEvent += (o, a) => Inside = true;
+                LeaveNotifyEvent += (o, a) => Inside = false;
+
+                da.ExposeEvent += (o, a) => {
+                    if (da.IsDrawable) {
+                        Gtk.Style.PaintHandle (da.Style, da.GdkWindow, da.State, ShadowType.In,
+                            a.Event.Area, this, "entry", 0, 0, da.Allocation.Width, da.Allocation.Height, Orientation);
+                    }
+                };
+            }
+
+            public Gtk.Orientation Orientation { get; set; }
+
+            private bool inside, dragging;
+            private bool Inside {
+                set {
+                    inside = value;
+                    GdkWindow.Cursor = dragging || inside ? resize_cursor : null;
+                }
+            }
+
+            private bool Dragging {
+                set {
+                    dragging = value;
+                    GdkWindow.Cursor = dragging || inside ? resize_cursor : null;
+                }
+            }
+
+            private static Gdk.Cursor resize_cursor = new Gdk.Cursor (Gdk.CursorType.SbHDoubleArrow);
         }
 
         private bool transitioning = false;



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]