banshee r3726 - in trunk/banshee: . src/Clients/Nereid/Nereid src/Core/Banshee.ThickClient src/Core/Banshee.ThickClient/Banshee.Gui src/Core/Banshee.ThickClient/Banshee.Gui.Widgets src/Libraries/Hyena.Gui src/Libraries/Hyena.Gui/Hyena.Gui src/Libraries/Hyena.Gui/Hyena.Widgets



Author: scottp
Date: Wed Apr  9 10:38:58 2008
New Revision: 3726
URL: http://svn.gnome.org/viewvc/banshee?rev=3726&view=rev

Log:
OK, I totally re-did the arrow button stuff. We still don't use the
standard Gtk MenuToolButton because I am WAY to cool for it.
It like _thought_ it was all cool enough to sit at my lunch table,
but I was all like Ut-Uh! So we now use the sufficiently cool and
totally custom MenuButton. This sucker is lean, mean, with an
emphasis on correctness. No hacky-hacky here. Nosiree. I'd
maybe entertain the idea that there's a better way to handle
the RepeatActionButton, but I'm seriously fine with it as-is.

* src/Clients/Nereid/Nereid/PlayerInterface.cs: Use the new stuff.

* src/Core/Banshee.ThickClient/Banshee.Gui/PlaybackShuffleActions.cs,
* src/Core/Banshee.ThickClient/Banshee.Gui/PlaybackRepeatActions.cs:
Added nice CreateMenu() method which does just what you think.

* src/Core/Banshee.ThickClient/Banshee.Gui.Widgets/NextArrowButton.cs:
* src/Libraries/Hyena.Gui/Hyena.Gui/IRadioActionGroup.cs:
* src/Libraries/Hyena.Gui/Hyena.Widgets/ArrowButton.cs:
* src/Libraries/Hyena.Gui/Hyena.Widgets/ActionGroupButton.cs:
* src/Libraries/Hyena.Gui/Hyena.Widgets/ActionButton.cs: Got rid of
these god-aweful classes.

* src/Core/Banshee.ThickClient/Banshee.Gui.Widgets/RepeatActionButton.cs:
Redone to use MenuButton.

* src/Libraries/Hyena.Gui/Hyena.Widgets/MenuButton.cs: This is the
lovely new widget. Pass it a widget (like a Button or a MenuButton,
for example) and it will menu-fy it! If showArrow is true, a
way-pretty arrow will appear to the side of the widget you pass,
providing access to the menu. If showArrow is false, the widget you
pass will get packed inside the button and clicking anywhere will
open the menu.

Added:
   trunk/banshee/src/Libraries/Hyena.Gui/Hyena.Widgets/MenuButton.cs
Removed:
   trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui.Widgets/NextArrowButton.cs
   trunk/banshee/src/Libraries/Hyena.Gui/Hyena.Gui/IRadioActionGroup.cs
   trunk/banshee/src/Libraries/Hyena.Gui/Hyena.Widgets/ActionButton.cs
   trunk/banshee/src/Libraries/Hyena.Gui/Hyena.Widgets/ActionGroupButton.cs
   trunk/banshee/src/Libraries/Hyena.Gui/Hyena.Widgets/ArrowButton.cs
Modified:
   trunk/banshee/ChangeLog
   trunk/banshee/src/Clients/Nereid/Nereid/PlayerInterface.cs
   trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui.Widgets/RepeatActionButton.cs
   trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui/PlaybackRepeatActions.cs
   trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui/PlaybackShuffleActions.cs
   trunk/banshee/src/Core/Banshee.ThickClient/Banshee.ThickClient.mdp
   trunk/banshee/src/Core/Banshee.ThickClient/Makefile.am
   trunk/banshee/src/Libraries/Hyena.Gui/Hyena.Gui.mdp
   trunk/banshee/src/Libraries/Hyena.Gui/Makefile.am

Modified: trunk/banshee/src/Clients/Nereid/Nereid/PlayerInterface.cs
==============================================================================
--- trunk/banshee/src/Clients/Nereid/Nereid/PlayerInterface.cs	(original)
+++ trunk/banshee/src/Clients/Nereid/Nereid/PlayerInterface.cs	Wed Apr  9 10:38:58 2008
@@ -35,6 +35,7 @@
 using Hyena.Gui;
 using Hyena.Data;
 using Hyena.Data.Gui;
+using Hyena.Widgets;
 
 using Banshee.ServiceStack;
 using Banshee.Sources;
@@ -147,7 +148,9 @@
             
             primary_vbox.PackStart (toolbar_alignment, false, false, 0);
             
-            NextArrowButton next_button = new NextArrowButton ();
+            Widget button = ActionService.PlaybackActions["NextAction"].CreateToolItem ();
+            Menu menu = ActionService.PlaybackActions.ShuffleActions.CreateMenu ();
+            MenuButton next_button = new MenuButton (button, menu, true);
             next_button.Show ();
             ActionService.PopulateToolbarPlaceholder (header_toolbar, "/HeaderToolbar/NextArrowButton", next_button);
             

Modified: trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui.Widgets/RepeatActionButton.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui.Widgets/RepeatActionButton.cs	(original)
+++ trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui.Widgets/RepeatActionButton.cs	Wed Apr  9 10:38:58 2008
@@ -29,26 +29,41 @@
 using System;
 using Gtk;
 
-using Hyena.Gui;
 using Hyena.Widgets;
 
 using Banshee.ServiceStack;
 
 namespace Banshee.Gui.Widgets
 {
-    public class RepeatActionButton : ActionGroupButton
+    public class RepeatActionButton : HBox
     {
-        private InterfaceActionService service = ServiceManager.Get<InterfaceActionService> ();
+        private PlaybackRepeatActions actions = ServiceManager.Get<InterfaceActionService> ().PlaybackActions.RepeatActions;
+        
+        private MenuButton button;
+        private HBox box = new HBox ();
+        private Image image = new Image ();
+        private Label label = new Label ();
         
         public RepeatActionButton ()
         {
-            ActionButtonStyle = ActionButtonStyle.BothHoriz;
-            IconSize = Gtk.IconSize.Menu;
-            Relief = ReliefStyle.None;
+            box.Spacing = 4;
+            label.UseUnderline = true;
+            image.IconSize = (int)IconSize.Menu;
+            
+            actions.Changed += delegate { OnActionChanged (); };
+            OnActionChanged ();
+            
+            box.PackStart (image, false, false, 0);
+            box.PackStart (label, true, true, 0);
+            button = new MenuButton (box, actions.CreateMenu (), false);
+            Add (button);
+            ShowAll ();
         }
         
-        protected override IRadioActionGroup ActionGroup {
-            get { return service.PlaybackActions.RepeatActions; }
+        private void OnActionChanged ()
+        {
+            image.IconName = actions.Active.IconName;
+            label.TextWithMnemonic = actions.Active.Label;
         }
     }
 }

Modified: trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui/PlaybackRepeatActions.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui/PlaybackRepeatActions.cs	(original)
+++ trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui/PlaybackRepeatActions.cs	Wed Apr  9 10:38:58 2008
@@ -40,7 +40,7 @@
 
 namespace Banshee.Gui
 {
-    public class PlaybackRepeatActions : BansheeActionGroup, IRadioActionGroup
+    public class PlaybackRepeatActions : BansheeActionGroup, IEnumerable<RadioAction>
     {
         private RadioAction active_action;
 
@@ -99,6 +99,16 @@
                 handler (o, args);
             }
         }
+            
+        public Menu CreateMenu ()
+        {
+            Menu menu = new Gtk.Menu ();
+            foreach (RadioAction action in this) {
+                menu.Append (action.CreateMenuItem ());
+            }
+            menu.ShowAll ();
+            return menu;
+        }
 
         public IEnumerator<RadioAction> GetEnumerator ()
         {

Modified: trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui/PlaybackShuffleActions.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui/PlaybackShuffleActions.cs	(original)
+++ trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui/PlaybackShuffleActions.cs	Wed Apr  9 10:38:58 2008
@@ -40,7 +40,7 @@
 
 namespace Banshee.Gui
 {
-    public class PlaybackShuffleActions : BansheeActionGroup, IRadioActionGroup
+    public class PlaybackShuffleActions : BansheeActionGroup, IEnumerable<RadioAction>
     {
         private RadioAction active_action;
         private PlaybackActions playback_actions;
@@ -112,6 +112,18 @@
                 handler (o, args);
             }
         }
+            
+        public Menu CreateMenu ()
+        {
+            Menu menu = new Menu ();
+            menu.Append (this["ShuffleOffAction"].CreateMenuItem ());
+            menu.Append (new SeparatorMenuItem ());
+            menu.Append (this["ShuffleSongAction"].CreateMenuItem ());
+            menu.Append (this["ShuffleArtistAction"].CreateMenuItem ());
+            menu.Append (this["ShuffleAlbumAction"].CreateMenuItem ());
+            menu.ShowAll ();
+            return menu;
+        }
 
         public IEnumerator<RadioAction> GetEnumerator ()
         {

Modified: trunk/banshee/src/Core/Banshee.ThickClient/Banshee.ThickClient.mdp
==============================================================================
--- trunk/banshee/src/Core/Banshee.ThickClient/Banshee.ThickClient.mdp	(original)
+++ trunk/banshee/src/Core/Banshee.ThickClient/Banshee.ThickClient.mdp	Wed Apr  9 10:38:58 2008
@@ -93,7 +93,6 @@
     <File name="Banshee.Collection.Gui/TerseTrackListView.cs" subtype="Code" buildaction="Compile" />
     <File name="Banshee.Collection.Gui/ColumnCellTrack.cs" subtype="Code" buildaction="Compile" />
     <File name="Banshee.Sources.Gui/ITrackModelSourceContents.cs" subtype="Code" buildaction="Compile" />
-    <File name="Banshee.Gui.Widgets/NextArrowButton.cs" subtype="Code" buildaction="Compile" />
     <File name="Banshee.Gui/PlaybackShuffleActions.cs" subtype="Code" buildaction="Compile" />
     <File name="Banshee.Gui.Dialogs/ExtensionManagerDialog.cs" subtype="Code" buildaction="Compile" />
   </Contents>

Modified: trunk/banshee/src/Core/Banshee.ThickClient/Makefile.am
==============================================================================
--- trunk/banshee/src/Core/Banshee.ThickClient/Makefile.am	(original)
+++ trunk/banshee/src/Core/Banshee.ThickClient/Makefile.am	Wed Apr  9 10:38:58 2008
@@ -41,7 +41,6 @@
 	Banshee.Gui.Widgets/ConnectedMessageBar.cs \
 	Banshee.Gui.Widgets/ConnectedSeekSlider.cs \
 	Banshee.Gui.Widgets/ConnectedVolumeButton.cs \
-	Banshee.Gui.Widgets/NextArrowButton.cs \
 	Banshee.Gui.Widgets/PlaylistMenuItem.cs \
 	Banshee.Gui.Widgets/RepeatActionButton.cs \
 	Banshee.Gui.Widgets/TrackInfoDisplay.cs \

Modified: trunk/banshee/src/Libraries/Hyena.Gui/Hyena.Gui.mdp
==============================================================================
--- trunk/banshee/src/Libraries/Hyena.Gui/Hyena.Gui.mdp	(original)
+++ trunk/banshee/src/Libraries/Hyena.Gui/Hyena.Gui.mdp	Wed Apr  9 10:38:58 2008
@@ -65,10 +65,7 @@
     <File name="Hyena.Query.Gui/TimeSpanQueryValueEntry.cs" subtype="Code" buildaction="Compile" />
     <File name="Hyena.Data.Gui/IListView.cs" subtype="Code" buildaction="Compile" />
     <File name="Hyena.Widgets/SmoothScrolledWindow.cs" subtype="Code" buildaction="Compile" />
-    <File name="Hyena.Gui/IRadioActionGroup.cs" subtype="Code" buildaction="Compile" />
-    <File name="Hyena.Widgets/ActionButton.cs" subtype="Code" buildaction="Compile" />
-    <File name="Hyena.Widgets/ArrowButton.cs" subtype="Code" buildaction="Compile" />
-    <File name="Hyena.Widgets/ActionGroupButton.cs" subtype="Code" buildaction="Compile" />
+    <File name="Hyena.Widgets/MenuButton.cs" subtype="Code" buildaction="Compile" />
   </Contents>
   <References>
     <ProjectReference type="Gac" localcopy="True" refto="System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />

Added: trunk/banshee/src/Libraries/Hyena.Gui/Hyena.Widgets/MenuButton.cs
==============================================================================
--- (empty file)
+++ trunk/banshee/src/Libraries/Hyena.Gui/Hyena.Widgets/MenuButton.cs	Wed Apr  9 10:38:58 2008
@@ -0,0 +1,136 @@
+//
+// MenuButton.cs
+//
+// Author:
+//   Scott Peterson <lunchtimemama gmail com>
+//
+// Copyright (c) 2008 Scott Peterson
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+using System;
+using Gtk;
+using Gdk;
+
+namespace Hyena.Widgets
+{
+    public class MenuButton : Container
+    {
+        private ToggleButton button = new ToggleButton ();
+        private HBox box = new HBox ();
+        private Alignment alignment;
+        private Arrow arrow;
+        private Widget button_widget;
+        private Menu menu;
+        private Widget size_widget;
+        
+        public MenuButton (Widget buttonWidget, Menu menu, bool showArrow)
+        {
+            button_widget = buttonWidget;
+            this.menu = menu;
+            menu.Deactivated += delegate { button.Active = false; };
+            
+            button.Parent = this;
+            button.FocusOnClick = false;
+            button.Relief = ReliefStyle.None;
+            button.Pressed += delegate { button.Active = true; ShowMenu (); };
+            button.Activated += delegate { ShowMenu (); };
+            
+            box.Parent = this;
+            
+            if (showArrow) {
+                box.PackStart (button_widget, true, true, 0);
+                alignment = new Alignment (0f, 0.5f, 0f, 0f);
+                arrow = new Arrow (ArrowType.Down, ShadowType.None);
+                alignment.Add (arrow);
+                box.PackStart (alignment, false, false, 5);
+                size_widget = box;
+            } else {
+                button.Add (button_widget);
+                size_widget = button;
+            }
+            
+            ShowAll ();
+        }
+        
+        public Widget ButtonWidget {
+            get { return button_widget; }
+        }
+        
+        public Menu Menu {
+            get { return menu; }
+        }
+        
+        protected override void OnRealized ()
+        {
+            WidgetFlags |= WidgetFlags.Realized | WidgetFlags.NoWindow;
+            GdkWindow = Parent.GdkWindow;
+        }
+        
+        protected override void OnSizeRequested (ref Requisition requisition)
+        {
+            requisition = size_widget.SizeRequest ();
+        }
+        
+        protected override void OnSizeAllocated (Rectangle allocation)
+        {
+            box.SizeAllocate (allocation);
+            button.SizeAllocate (allocation);
+            base.OnSizeAllocated (allocation);
+        }
+        
+        protected override void ForAll (bool include_internals, Callback callback)
+        {
+            callback (button);
+            callback (box);
+        }
+        
+        protected void ShowMenu ()
+        {
+            menu.Popup (null, null, PositionMenu, 1, Gtk.Global.CurrentEventTime);
+        }
+
+        private void PositionMenu (Menu menu, out int x, out int y, out bool push_in) 
+        {
+            Gtk.Requisition menu_req = menu.SizeRequest ();
+            int monitor_num = Screen.GetMonitorAtWindow (GdkWindow);
+            Gdk.Rectangle monitor = Screen.GetMonitorGeometry (monitor_num < 0 ? 0 : monitor_num);
+
+            GdkWindow.GetOrigin (out x, out y);
+            
+            y += Allocation.Y;
+            x += Allocation.X + (Direction == TextDirection.Ltr
+                ? Math.Max (Allocation.Width - menu_req.Width, 0)
+                : - (menu_req.Width - Allocation.Width));
+            
+            if (y + Allocation.Height + menu_req.Height <= monitor.Y + monitor.Height) {
+                y += Allocation.Height;
+            } else if (y - menu_req.Height >= monitor.Y) {
+                y -= menu_req.Height;
+            } else if (monitor.Y + monitor.Height - (y + Allocation.Height) > y) {
+                y += Allocation.Height;
+            } else {
+                y -= menu_req.Height;
+            }
+
+            push_in = false;
+        }
+    }
+}

Modified: trunk/banshee/src/Libraries/Hyena.Gui/Makefile.am
==============================================================================
--- trunk/banshee/src/Libraries/Hyena.Gui/Makefile.am	(original)
+++ trunk/banshee/src/Libraries/Hyena.Gui/Makefile.am	Wed Apr  9 10:38:58 2008
@@ -36,7 +36,6 @@
 	Hyena.Gui/EntryInsertAction.cs \
 	Hyena.Gui/EntryUndoAdapter.cs \
 	Hyena.Gui/GtkUtilities.cs \
-	Hyena.Gui/IRadioActionGroup.cs \
 	Hyena.Gui/PangoCairoHelper.cs \
 	Hyena.Gui/ShadingTestWindow.cs \
 	Hyena.Query.Gui/DateQueryValueEntry.cs \
@@ -51,14 +50,12 @@
 	Hyena.Query.Gui/RelativeTimeSpanQueryValueEntry.cs \
 	Hyena.Query.Gui/StringQueryValueEntry.cs \
 	Hyena.Query.Gui/TimeSpanQueryValueEntry.cs \
-	Hyena.Widgets/ActionButton.cs \
-	Hyena.Widgets/ActionGroupButton.cs \
 	Hyena.Widgets/AnimatedBox.cs \
 	Hyena.Widgets/AnimatedHBox.cs \
 	Hyena.Widgets/AnimatedImage.cs \
 	Hyena.Widgets/AnimatedVBox.cs \
 	Hyena.Widgets/AnimatedWidget.cs \
-	Hyena.Widgets/ArrowButton.cs \
+	Hyena.Widgets/MenuButton.cs \
 	Hyena.Widgets/MessageBar.cs \
 	Hyena.Widgets/RoundedFrame.cs \
 	Hyena.Widgets/ScrolledWindow.cs \



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