banshee r3108 - in trunk/banshee: . src/Core/Banshee.Services/Banshee.Playlist src/Core/Banshee.Services/Banshee.Sources src/Core/Banshee.ThickClient/Banshee.Sources.Gui src/Core/Hyena.Gui src/Core/Hyena.Gui/Hyena.Data.Gui src/Core/Hyena.Gui/Hyena.Gui.Theatre src/Core/Hyena.Gui/Hyena.Widgets
- From: abock svn gnome org
- To: svn-commits-list gnome org
- Subject: banshee r3108 - in trunk/banshee: . src/Core/Banshee.Services/Banshee.Playlist src/Core/Banshee.Services/Banshee.Sources src/Core/Banshee.ThickClient/Banshee.Sources.Gui src/Core/Hyena.Gui src/Core/Hyena.Gui/Hyena.Data.Gui src/Core/Hyena.Gui/Hyena.Gui.Theatre src/Core/Hyena.Gui/Hyena.Widgets
- Date: Thu, 31 Jan 2008 03:01:06 +0000 (GMT)
Author: abock
Date: Thu Jan 31 03:01:05 2008
New Revision: 3108
URL: http://svn.gnome.org/viewvc/banshee?rev=3108&view=rev
Log:
2008-01-30 Aaron Bockover <abock gnome org>
* src/Core/Banshee.Services/Banshee.Playlist/PlaylistSource.cs:
* src/Core/Banshee.Services/Banshee.Sources/Source.cs:
Added UserNotifyUpdated event that sources can use to trigger
notifications or visual cues in the source view
* src/Core/Banshee.ThickClient/Banshee.Sources.Gui/SourceRowRenderer.cs:
* src/Core/Banshee.ThickClient/Banshee.Sources.Gui/SourceView.cs:
Use the new Hyena theatre stage/actors to animate update notifications on
source rows in the source views
* src/Core/Hyena.Gui/Hyena.Data.Gui/ListViewGraphics.cs: Added a method
for drawing a flat row highlight
* src/Core/Hyena.Gui/Hyena.Gui.Theatre/Stage.cs: An object that manages
timeouts for a set of Actors bound to targets of T; used for animating
collections of objects bound to actors
* src/Core/Hyena.Gui/Hyena.Gui.Theatre/Actor.cs: An object bound to
a target of T with life span and percentage properties used for animations
* src/Core/Hyena.Gui/Hyena.Widgets/RoundedFrame.cs: Remove redundant
BorderWidth property
Added:
trunk/banshee/src/Core/Hyena.Gui/Hyena.Gui.Theatre/
trunk/banshee/src/Core/Hyena.Gui/Hyena.Gui.Theatre/Actor.cs
trunk/banshee/src/Core/Hyena.Gui/Hyena.Gui.Theatre/Stage.cs
Modified:
trunk/banshee/ChangeLog
trunk/banshee/src/Core/Banshee.Services/Banshee.Playlist/PlaylistSource.cs
trunk/banshee/src/Core/Banshee.Services/Banshee.Sources/Source.cs
trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Sources.Gui/SourceRowRenderer.cs
trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Sources.Gui/SourceView.cs
trunk/banshee/src/Core/Hyena.Gui/Hyena.Data.Gui/ListViewGraphics.cs
trunk/banshee/src/Core/Hyena.Gui/Hyena.Gui.mdp
trunk/banshee/src/Core/Hyena.Gui/Hyena.Widgets/RoundedFrame.cs
trunk/banshee/src/Core/Hyena.Gui/Makefile.am
Modified: trunk/banshee/src/Core/Banshee.Services/Banshee.Playlist/PlaylistSource.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.Services/Banshee.Playlist/PlaylistSource.cs (original)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.Playlist/PlaylistSource.cs Thu Jan 31 03:01:05 2008
@@ -202,6 +202,7 @@
return;
WithTrackSelection (from, AddTrackRange);
+ OnUserNotifyUpdated ();
}
protected virtual void AddTrackRange (TrackListDatabaseModel from, RangeCollection.Range range)
Modified: trunk/banshee/src/Core/Banshee.Services/Banshee.Sources/Source.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.Services/Banshee.Sources/Source.cs (original)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.Sources/Source.cs Thu Jan 31 03:01:05 2008
@@ -48,6 +48,7 @@
private List<Source> child_sources = new List<Source>();
public event EventHandler Updated;
+ public event EventHandler UserNotifyUpdated;
public event SourceEventHandler ChildSourceAdded;
public event SourceEventHandler ChildSourceRemoved;
@@ -205,6 +206,14 @@
}
}
+ protected virtual void OnUserNotifyUpdated()
+ {
+ EventHandler handler = UserNotifyUpdated;
+ if(handler != null) {
+ handler(this, EventArgs.Empty);
+ }
+ }
+
#endregion
#region Private Methods
Modified: trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Sources.Gui/SourceRowRenderer.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Sources.Gui/SourceRowRenderer.cs (original)
+++ trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Sources.Gui/SourceRowRenderer.cs Thu Jan 31 03:01:05 2008
@@ -31,6 +31,9 @@
using Gdk;
using Pango;
+using Hyena.Data.Gui;
+using Hyena.Gui.Theatre;
+
using Banshee.ServiceStack;
namespace Banshee.Sources.Gui
@@ -93,6 +96,16 @@
} else if (path != null && path.Equals (view.HighlightedPath)) {
view.Graphics.DrawRowSelection (view.Cr, background_area.X + 1, background_area.Y + 1,
background_area.Width - 2, background_area.Height - 2, false);
+ } else if (view.NotifyStage.ActorCount > 0) {
+ TreeIter iter;
+ if (view.Model.GetIter (out iter, path) && view.NotifyStage.Contains (iter)) {
+ Actor<TreeIter> actor = view.NotifyStage[iter];
+ Cairo.Color color = view.Graphics.GetWidgetColor (GtkColorClass.Background, StateType.Selected);
+ color.A = 1.0 - actor.Percent;
+
+ view.Graphics.DrawFlatRowHighlight (view.Cr, background_area.X + 1, background_area.Y + 1,
+ background_area.Width - 2, background_area.Height - 2, color);
+ }
}
int title_layout_width = 0, title_layout_height = 0;
Modified: trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Sources.Gui/SourceView.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Sources.Gui/SourceView.cs (original)
+++ trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Sources.Gui/SourceView.cs Thu Jan 31 03:01:05 2008
@@ -27,10 +27,12 @@
//
using System;
+using System.Collections.Generic;
using Gtk;
using Cairo;
using Hyena.Data.Gui;
+using Hyena.Gui.Theatre;
using Banshee.ServiceStack;
using Banshee.Sources;
@@ -53,6 +55,9 @@
private ListViewGraphics graphics;
private Cairo.Context cr;
+ private uint user_update_timeout_id = 0;
+ private Stage<TreeIter> notify_stage = new Stage<TreeIter> ();
+
private TreeStore store;
private TreeViewColumn focus_column;
private TreePath highlight_path;
@@ -120,6 +125,11 @@
ServiceManager.PlaybackController.SourceChanged += delegate {
QueueDraw();
};
+
+ notify_stage.ActorStep += delegate (Actor<TreeIter> actor) {
+ Gdk.Rectangle rect = GetBackgroundArea (store.GetPath (actor.Target), focus_column);
+ QueueDrawArea (rect.X, rect.Y, rect.Width, rect.Height);
+ };
}
#endregion
@@ -326,8 +336,12 @@
}
}
- source.ChildSourceAdded += delegate (SourceEventArgs e) { AddSource (e.Source, iter); };
- source.ChildSourceRemoved += delegate (SourceEventArgs e) { RemoveSource(e.Source); };
+ // delegate (SourceEventArgs e) { AddSource (e.Source, iter); };
+ // delegate (SourceEventArgs e) { RemoveSource(e.Source); };
+
+ source.ChildSourceAdded += OnSourceChildSourceAdded;
+ source.ChildSourceRemoved += OnSourceChildSourceRemoved;
+ source.UserNotifyUpdated += OnSourceUserNotifyUpdated;
if (source.Expanded || (source.AutoExpand != null && source.AutoExpand.Value)) {
Expand (iter);
@@ -348,6 +362,10 @@
if (!iter.Equals (TreeIter.Zero)) {
store.Remove (ref iter);
}
+
+ source.ChildSourceAdded -= OnSourceChildSourceAdded;
+ source.ChildSourceRemoved -= OnSourceChildSourceRemoved;
+ source.UserNotifyUpdated -= OnSourceUserNotifyUpdated;
UpdateView ();
}
@@ -365,7 +383,27 @@
AddSource (source);
}
}
+
+ private void OnSourceChildSourceAdded (SourceEventArgs args)
+ {
+ AddSource (args.Source, FindSource (args.Source.Parent));
+ }
+
+ private void OnSourceChildSourceRemoved (SourceEventArgs args)
+ {
+ RemoveSource (args.Source);
+ }
+ private void OnSourceUserNotifyUpdated (object o, EventArgs args)
+ {
+ TreeIter iter = FindSource ((Source)o);
+ if (iter.Equals (TreeIter.Zero)) {
+ return;
+ }
+
+ notify_stage.AddOrReset (iter);
+ }
+
#endregion
#region List/View Utility Methods
@@ -502,6 +540,10 @@
internal ListViewGraphics Graphics {
get { return graphics; }
}
+
+ internal Stage<TreeIter> NotifyStage {
+ get { return notify_stage; }
+ }
#endregion
Modified: trunk/banshee/src/Core/Hyena.Gui/Hyena.Data.Gui/ListViewGraphics.cs
==============================================================================
--- trunk/banshee/src/Core/Hyena.Gui/Hyena.Data.Gui/ListViewGraphics.cs (original)
+++ trunk/banshee/src/Core/Hyena.Gui/Hyena.Data.Gui/ListViewGraphics.cs Thu Jan 31 03:01:05 2008
@@ -305,6 +305,13 @@
CairoExtensions.RoundedRectangle(cr, x + 0.5, y + 0.5, width - 1, height - 1, BorderRadius);
cr.Stroke();
}
+
+ public void DrawFlatRowHighlight(Cairo.Context cr, int x, int y, int width, int height, Cairo.Color color)
+ {
+ cr.Color = color;
+ CairoExtensions.RoundedRectangle(cr, x, y, width, height, BorderRadius);
+ cr.Fill();
+ }
public void DrawRowRule(Cairo.Context cr, int x, int y, int width, int height)
{
Added: trunk/banshee/src/Core/Hyena.Gui/Hyena.Gui.Theatre/Actor.cs
==============================================================================
--- (empty file)
+++ trunk/banshee/src/Core/Hyena.Gui/Hyena.Gui.Theatre/Actor.cs Thu Jan 31 03:01:05 2008
@@ -0,0 +1,90 @@
+//
+// Actor.cs
+//
+// Author:
+// Aaron Bockover <abockover novell com>
+//
+// Copyright (C) 2008 Novell, Inc.
+//
+// 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;
+
+namespace Hyena.Gui.Theatre
+{
+ public class Actor<T>
+ {
+ private T target;
+
+ private DateTime start_time;
+ private uint duration;
+ private double frames;
+ private double percent;
+
+ public Actor (T target, uint duration)
+ {
+ this.target = target;
+ this.duration = duration;
+ Reset ();
+ }
+
+ public void Reset ()
+ {
+ start_time = DateTime.Now;
+ frames = 0.0;
+ percent = 0.0;
+ }
+
+ public virtual void Step ()
+ {
+ percent = (DateTime.Now - start_time).TotalMilliseconds / duration;
+ frames++;
+ }
+
+ public bool Expired {
+ get { return percent >= 1.0; }
+ }
+
+ public T Target {
+ get { return target; }
+ }
+
+ public double Duration {
+ get { return duration; }
+ }
+
+ public DateTime StartTime {
+ get { return start_time; }
+ }
+
+ public double Frames {
+ get { return frames; }
+ }
+
+ public double FramesPerSecond {
+ get { return frames / ((double)duration / 1000.0); }
+ }
+
+ public double Percent {
+ get { return Math.Max (0.0, Math.Min (1.0, percent)); }
+ }
+ }
+}
Added: trunk/banshee/src/Core/Hyena.Gui/Hyena.Gui.Theatre/Stage.cs
==============================================================================
--- (empty file)
+++ trunk/banshee/src/Core/Hyena.Gui/Hyena.Gui.Theatre/Stage.cs Thu Jan 31 03:01:05 2008
@@ -0,0 +1,235 @@
+//
+// Stage.cs
+//
+// Author:
+// Aaron Bockover <abockover novell com>
+//
+// Copyright (C) 2008 Novell, Inc.
+//
+// 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 System.Collections.Generic;
+
+namespace Hyena.Gui.Theatre
+{
+ public class Stage<T>
+ {
+ public delegate void ActorStepHandler (Actor<T> actor);
+
+ private Dictionary<T, Actor<T>> actors = new Dictionary<T, Actor<T>> ();
+ private uint timeout_id;
+
+ private uint update_frequency = 30;
+ private uint default_duration = 1000;
+ private bool playing = true;
+
+ public event ActorStepHandler ActorStep;
+ public event EventHandler Iteration;
+
+ public Stage ()
+ {
+ }
+
+ public Stage (uint actorDuration)
+ {
+ default_duration = actorDuration;
+ }
+
+ public Actor<T> this[T target] {
+ get {
+ if (actors.ContainsKey (target)) {
+ return actors[target];
+ }
+
+ return null;
+ }
+ }
+
+ public bool Contains (T target)
+ {
+ return actors.ContainsKey (target);
+ }
+
+ public Actor<T> Add (T target)
+ {
+ lock (this) {
+ return Add (target, default_duration);
+ }
+ }
+
+ public Actor<T> Add (T target, uint duration)
+ {
+ lock (this) {
+ if (Contains (target)) {
+ throw new InvalidOperationException ("Stage already contains this actor");
+ }
+
+ Actor<T> actor = new Actor<T> (target, duration);
+ actors.Add (target, actor);
+
+ CheckTimeout ();
+
+ return actor;
+ }
+ }
+
+ public Actor<T> AddOrReset (T target)
+ {
+ lock (this) {
+ if (Contains (target)) {
+ Actor<T> actor = this[target];
+ actor.Reset ();
+
+ CheckTimeout ();
+
+ return actor;
+ }
+
+ return Add (target);
+ }
+ }
+
+ public void Reset (T target)
+ {
+ lock (this) {
+ if (!Contains (target)) {
+ throw new InvalidOperationException ("Stage does not contain this actor");
+ }
+
+ CheckTimeout ();
+
+ this[target].Reset ();
+ }
+ }
+
+ private void CheckTimeout ()
+ {
+ if ((!Playing || actors.Count == 0) && timeout_id > 0) {
+ GLib.Source.Remove (timeout_id);
+ timeout_id = 0;
+ return;
+ } else if (Playing && actors.Count > 0 && timeout_id <= 0) {
+ timeout_id = GLib.Timeout.Add (update_frequency, OnTimeout);
+ return;
+ }
+ }
+
+ private bool OnTimeout ()
+ {
+ if (!Playing || actors.Count == 0) {
+ timeout_id = 0;
+ return false;
+ }
+
+ Queue<Actor<T>> expired_actors = new Queue<Actor<T>> ();
+
+ foreach (KeyValuePair<T, Actor<T>> entry in actors) {
+ entry.Value.Step ();
+ OnActorStep (entry.Value);
+
+ if (entry.Value.Expired) {
+ expired_actors.Enqueue (entry.Value);
+ }
+ }
+
+ while (expired_actors.Count > 0) {
+ actors.Remove (expired_actors.Dequeue ().Target);
+ }
+
+ OnIteration ();
+
+ return true;
+ }
+
+ protected virtual void OnActorStep (Actor<T> actor)
+ {
+ ActorStepHandler handler = ActorStep;
+ if (handler != null) {
+ handler (actor);
+ }
+ }
+
+ protected virtual void OnIteration ()
+ {
+ EventHandler handler = Iteration;
+ if (handler != null) {
+ handler (this, EventArgs.Empty);
+ }
+ }
+
+ public void Play ()
+ {
+ lock (this) {
+ Playing = true;
+ }
+ }
+
+ public void Pause ()
+ {
+ lock (this) {
+ Playing = false;
+ }
+ }
+
+ public void Exeunt ()
+ {
+ lock (this) {
+ actors.Clear ();
+ CheckTimeout ();
+ }
+ }
+
+ public uint DefaultActorDuration {
+ get { return default_duration; }
+ set { lock (this) { default_duration = value; } }
+ }
+
+ public bool Playing {
+ get { return playing; }
+ set {
+ lock (this) {
+ if (playing == value) {
+ return;
+ }
+
+ playing = value;
+ CheckTimeout ();
+ }
+ }
+ }
+
+ public uint UpdateFrequency {
+ get { return update_frequency; }
+ set {
+ lock (this) {
+ bool _playing = Playing;
+ update_frequency = value;
+ Playing = _playing;
+ }
+ }
+ }
+
+ public int ActorCount {
+ get { return actors.Count; }
+ }
+ }
+}
Modified: trunk/banshee/src/Core/Hyena.Gui/Hyena.Gui.mdp
==============================================================================
--- trunk/banshee/src/Core/Hyena.Gui/Hyena.Gui.mdp (original)
+++ trunk/banshee/src/Core/Hyena.Gui/Hyena.Gui.mdp Thu Jan 31 03:01:05 2008
@@ -28,9 +28,10 @@
<File name="Hyena.Gui/GtkUtilities.cs" subtype="Code" buildaction="Compile" />
<File name="Hyena.Data.Gui/CellContext.cs" subtype="Code" buildaction="Compile" />
<File name="Hyena.Data.Gui/IHeaderCell.cs" subtype="Code" buildaction="Compile" />
- <File name="Hyena.Widgets" subtype="Directory" buildaction="Compile" />
<File name="Hyena.Widgets/ScrolledWindow.cs" subtype="Code" buildaction="Compile" />
<File name="Hyena.Widgets/RoundedFrame.cs" subtype="Code" buildaction="Compile" />
+ <File name="Hyena.Gui.Theatre/Actor.cs" subtype="Code" buildaction="Compile" />
+ <File name="Hyena.Gui.Theatre/Stage.cs" subtype="Code" buildaction="Compile" />
</Contents>
<References>
<ProjectReference type="Gac" localcopy="True" refto="System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
Modified: trunk/banshee/src/Core/Hyena.Gui/Hyena.Widgets/RoundedFrame.cs
==============================================================================
--- trunk/banshee/src/Core/Hyena.Gui/Hyena.Widgets/RoundedFrame.cs (original)
+++ trunk/banshee/src/Core/Hyena.Gui/Hyena.Widgets/RoundedFrame.cs Thu Jan 31 03:01:05 2008
@@ -39,7 +39,6 @@
{
private ListViewGraphics graphics;
private int frame_width = 4;
- private int border_width = 0;
private Widget child;
private Gdk.Rectangle child_allocation;
@@ -73,8 +72,8 @@
width = height = 80;
}
- SetSizeRequest (width + (border_width + frame_width) * 2,
- height + (border_width + frame_width) * 2);
+ SetSizeRequest (width + ((int)BorderWidth + frame_width) * 2,
+ height + ((int)BorderWidth + frame_width) * 2);
}
protected override void OnSizeAllocated (Gdk.Rectangle allocation)
@@ -87,11 +86,11 @@
return;
}
- child_allocation.X = border_width + frame_width;
- child_allocation.Y = border_width + frame_width;
+ child_allocation.X = (int)BorderWidth + frame_width;
+ child_allocation.Y = (int)BorderWidth + frame_width;
child_allocation.Width = (int)Math.Max (1, Allocation.Width - child_allocation.X * 2);
child_allocation.Height = (int)Math.Max (1, Allocation.Height - child_allocation.Y -
- border_width - frame_width);
+ (int)BorderWidth - frame_width);
child_allocation.X += Allocation.X;
child_allocation.Y += Allocation.Y;
@@ -147,12 +146,5 @@
#endregion
- public int BorderWidth {
- get { return border_width; }
- set {
- border_width = value;
- QueueResize ();
- }
- }
}
}
Modified: trunk/banshee/src/Core/Hyena.Gui/Makefile.am
==============================================================================
--- trunk/banshee/src/Core/Hyena.Gui/Makefile.am (original)
+++ trunk/banshee/src/Core/Hyena.Gui/Makefile.am Thu Jan 31 03:01:05 2008
@@ -16,6 +16,8 @@
Hyena.Data.Gui/SortableColumn.cs \
Hyena.Gui.Dialogs/ExceptionDialog.cs \
Hyena.Gui.Dialogs/VersionInformationDialog.cs \
+ Hyena.Gui.Theatre/Actor.cs \
+ Hyena.Gui.Theatre/Stage.cs \
Hyena.Gui/CairoExtensions.cs \
Hyena.Gui/CleanRoomStartup.cs \
Hyena.Gui/EntryEraseAction.cs \
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]