Skip to content

Commit

Permalink
iOS: MobileLibraryBrowser: Now loading album art in background.
Browse files Browse the repository at this point in the history
MobileLibraryBrowserPresenter: Added action for loading album art. Will need to add an action for canceling fetching album art later.

Related to issue #405 and issue #408.
  • Loading branch information
ycastonguay committed Mar 4, 2013
1 parent 8b665c4 commit e0251ac
Show file tree
Hide file tree
Showing 6 changed files with 147 additions and 9 deletions.
2 changes: 1 addition & 1 deletion MPfm/MPfm.Library/Database/DatabaseFacade.cs
Expand Up @@ -284,7 +284,7 @@ public List<string> SelectDistinctArtistNames(AudioFileFormat audioFileFormat)
{
sql.AppendLine(" WHERE ArtistName = '" + FormatSQLValue(artistName) + "' ");
}
sql.AppendLine(" ORDER BY ArtistName");
sql.AppendLine(" ORDER BY ArtistName, AlbumTitle ");

// Select distinct
List<Tuple<object, object>> listTuple = _gateway.SelectTuple(sql.ToString());
Expand Down
22 changes: 22 additions & 0 deletions MPfm/MPfm.MVP/Presenters/MobileLibraryBrowserPresenter.cs
Expand Up @@ -18,6 +18,8 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using MPfm.MVP.Messages;
using MPfm.MVP.Models;
using MPfm.MVP.Navigation;
Expand All @@ -42,6 +44,7 @@ public class MobileLibraryBrowserPresenter : BasePresenter<IMobileLibraryBrowser
private readonly IAudioFileCacheService _audioFileCacheService;
private readonly SongBrowserQueryEntity _query;

private Task _currentTask;
private List<LibraryBrowserEntity> _items;

public AudioFileFormat Filter { get; private set; }
Expand All @@ -59,13 +62,15 @@ public class MobileLibraryBrowserPresenter : BasePresenter<IMobileLibraryBrowser
_audioFileCacheService = audioFileCacheService;

Filter = AudioFileFormat.All;
_currentTask = Task.Factory.StartNew(() => { });
}

public override void BindView(IMobileLibraryBrowserView view)
{
base.BindView(view);

view.OnItemClick = OnItemClick;
view.OnRequestAlbumArt = RequestAlbumArt;

// Subscribe to any audio file cache update so we can update this screen
_messengerHub.Subscribe<AudioFileCacheUpdatedMessage>(AudioFileCacheUpdated);
Expand All @@ -78,6 +83,23 @@ private void AudioFileCacheUpdated(AudioFileCacheUpdatedMessage audioFileCacheUp
RefreshLibraryBrowser();
}

private void RequestAlbumArt(string artistName, string albumTitle)
{
// Only run one task at a time.
_currentTask = _currentTask.ContinueWith(t => {
// Get the file path of the first file in the album
var audioFiles = _libraryService.SelectAudioFiles(AudioFileFormat.All, artistName, albumTitle, string.Empty);
var audioFile = (audioFiles != null && audioFiles.Count() > 0) ? audioFiles.ElementAt(0) : null;
if (audioFile != null)
{
// Update with with album art byte array
byte[] bytesImage = AudioFile.ExtractImageByteArrayForAudioFile(audioFile.FilePath);
View.RefreshAlbumArtCell(artistName, albumTitle, bytesImage);
}
});
}

private void OnItemClick(int i)
{
// PLAYLIST TAB: Playlists --> Player
Expand Down
2 changes: 2 additions & 0 deletions MPfm/MPfm.MVP/Views/IMobileLibraryBrowserView.cs
Expand Up @@ -27,8 +27,10 @@ namespace MPfm.MVP.Views
public interface IMobileLibraryBrowserView : IBaseView
{
Action<int> OnItemClick { get; set; }
Action<string, string> OnRequestAlbumArt { get; set; }

void RefreshLibraryBrowser(IEnumerable<LibraryBrowserEntity> entities, MobileLibraryBrowserType browserType, string navigationBarTitle);
void RefreshAlbumArtCell(string artistName, string albumTitle, byte[] albumArtData);
}

public enum MobileLibraryBrowserType
Expand Down
Expand Up @@ -18,17 +18,19 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using MonoTouch.Foundation;
using MonoTouch.UIKit;
using MPfm.iOS.Classes.Controllers.Base;
using MPfm.iOS.Classes.Delegates;
using MPfm.iOS.Classes.Controls;
using MPfm.MVP.Views;
using MPfm.MVP.Models;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using MPfm.MVP.Models;
using MPfm.MVP.Views;
using MPfm.Sound.AudioFiles;
using MonoTouch.CoreAnimation;
using MonoTouch.CoreGraphics;
using MonoTouch.Foundation;
using MonoTouch.UIKit;
using MPfm.iOS.Classes.Controllers.Base;
using MPfm.iOS.Classes.Controls;
using MPfm.iOS.Classes.Delegates;

namespace MPfm.iOS.Classes.Controllers
{
Expand All @@ -38,6 +40,7 @@ public partial class MobileLibraryBrowserViewController : BaseViewController, IM
private string _cellIdentifier = "MobileLibraryBrowserCell";
private string _navigationBarTitle = string.Empty;
private MobileLibraryBrowserType _browserType;
private Task _currentTask;

public MobileLibraryBrowserViewController(Action<IBaseView> onViewReady)
: base (onViewReady, UserInterfaceIdiomIsPhone ? "MobileLibraryBrowserViewController_iPhone" : "MobileLibraryBrowserViewController_iPad", null)
Expand All @@ -55,6 +58,7 @@ public override void ViewDidLoad()
lblSubtitle1.Font = UIFont.FromName("OstrichSans-Black", 12);
lblSubtitle2.Font = UIFont.FromName("OstrichSans-Black", 12);

_currentTask = Task.Factory.StartNew (() => { });

//lblArtistName.SizeToFit();
//lblAlbumTitle.SizeToFit();
Expand Down Expand Up @@ -103,11 +107,15 @@ public UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
cell = new UITableViewCell(cellStyle, _cellIdentifier);

// Set title
cell.Tag = indexPath.Row;
cell.TextLabel.Text = _items[indexPath.Row].Title;
//cell.DetailTextLabel.Text = _items[indexPath.Row].

if (_browserType == MobileLibraryBrowserType.Albums)
cell.ImageView.Image = UIImage.FromBundle("Images/icon114");
{
cell.ImageView.Image = UIImage.FromBundle("Images/emptyalbumart");
OnRequestAlbumArt(_items[indexPath.Row].Query.ArtistName, _items[indexPath.Row].Query.AlbumTitle);
}

// Set font
//cell.TextLabel.Font = UIFont.FromName("Junction", 20);
Expand All @@ -130,7 +138,41 @@ public void RowSelected(UITableView tableView, NSIndexPath indexPath)
#region IMobileLibraryBrowserView implementation

public Action<int> OnItemClick { get; set; }
public Action<string, string> OnRequestAlbumArt { get; set; }

public void RefreshAlbumArtCell(string artistName, string albumTitle, byte[] albumArtData)
{
InvokeOnMainThread(() => {
// Get item from list
var item = _items.FirstOrDefault(x => x.Query.ArtistName == artistName && x.Query.AlbumTitle == albumTitle);
if(item == null)
return;
// Get cell from item
int index = _items.IndexOf(item);
var cell = tableView.VisibleCells.FirstOrDefault(x => x.Tag == index);
if(cell == null)
return;
// Load image
_currentTask = _currentTask.ContinueWith(t => {
NSData imageData = NSData.FromArray(albumArtData);
UIImage imageNotResized = UIImage.LoadFromData(imageData);
UIImage image = ScaleImage(imageNotResized, (int)cell.Bounds.Height * 2);
InvokeOnMainThread(() => {
if(cell != null)
{
if(cell.ImageView != null)
{
cell.ImageView.Image = image;
}
}
});
});
});
}

public void RefreshLibraryBrowser(IEnumerable<LibraryBrowserEntity> entities, MobileLibraryBrowserType browserType, string navigationBarTitle)
{
InvokeOnMainThread(() => {
Expand Down Expand Up @@ -178,6 +220,77 @@ public void RefreshLibraryBrowser(IEnumerable<LibraryBrowserEntity> entities, Mo

#endregion

public static UIImage ScaleImage(UIImage image, int maxSize)
{
UIImage res;

using (CGImage imageRef = image.CGImage)
{
CGImageAlphaInfo alphaInfo = imageRef.AlphaInfo;
CGColorSpace colorSpaceInfo = CGColorSpace.CreateDeviceRGB();
if (alphaInfo == CGImageAlphaInfo.None)
{
alphaInfo = CGImageAlphaInfo.NoneSkipLast;
}

int width, height;

width = imageRef.Width;
height = imageRef.Height;


if (height >= width)
{
width = (int)Math.Floor((double)width * ((double)maxSize / (double)height));
height = maxSize;
}
else
{
height = (int)Math.Floor((double)height * ((double)maxSize / (double)width));
width = maxSize;
}


CGBitmapContext bitmap;

if (image.Orientation == UIImageOrientation.Up || image.Orientation == UIImageOrientation.Down)
{
bitmap = new CGBitmapContext(IntPtr.Zero, width, height, imageRef.BitsPerComponent, imageRef.BytesPerRow, colorSpaceInfo, alphaInfo);
}
else
{
bitmap = new CGBitmapContext(IntPtr.Zero, height, width, imageRef.BitsPerComponent, imageRef.BytesPerRow, colorSpaceInfo, alphaInfo);
}

switch (image.Orientation)
{
case UIImageOrientation.Left:
bitmap.RotateCTM((float)Math.PI / 2);
bitmap.TranslateCTM(0, -height);
break;
case UIImageOrientation.Right:
bitmap.RotateCTM(-((float)Math.PI / 2));
bitmap.TranslateCTM(-width, 0);
break;
case UIImageOrientation.Up:
break;
case UIImageOrientation.Down:
bitmap.TranslateCTM(width, height);
bitmap.RotateCTM(-(float)Math.PI);
break;
}

bitmap.DrawImage(new Rectangle(0, 0, width, height), imageRef);


res = UIImage.FromImage(bitmap.ToImage());
bitmap = null;

}


return res;
}
}
}

Binary file added MPfm/MPfm.iOS/Images/emptyalbumart.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions MPfm/MPfm.iOS/MPfm.iOS.csproj
Expand Up @@ -244,6 +244,7 @@
<BundleResource Include="Resources\Default.png" />
<BundleResource Include="Resources\Default%402x.png" />
<BundleResource Include="Resources\Default-568h%402x.png" />
<BundleResource Include="Images\emptyalbumart.png" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\MPfm.Core\MPfm.Core.iOS.csproj">
Expand Down

0 comments on commit e0251ac

Please sign in to comment.