Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/ycastonguay/MPfm
Browse files Browse the repository at this point in the history
  • Loading branch information
ycastonguay committed Aug 31, 2013
2 parents 59a7be6 + 94debbf commit b09686c
Show file tree
Hide file tree
Showing 18 changed files with 438 additions and 216 deletions.
22 changes: 18 additions & 4 deletions MPfm/MPfm.Android/Classes/Activities/PlaylistActivity.cs
Expand Up @@ -30,6 +30,7 @@
using MPfm.MVP.Views;
using MPfm.Sound.AudioFiles;
using MPfm.Sound.Playlists;
using org.sessionsapp.android;

namespace MPfm.Android
{
Expand All @@ -39,9 +40,10 @@ public class PlaylistActivity : BaseActivity, IPlaylistView
private MobileNavigationManager _navigationManager;
Button _btnNew;
Button _btnShuffle;
ListView _listView;
CustomListView _listView;
PlaylistListAdapter _listAdapter;
Playlist _playlist;
string _sourceActivityType;

protected override void OnCreate(Bundle bundle)
{
Expand All @@ -58,16 +60,27 @@ protected override void OnCreate(Bundle bundle)
_btnShuffle = FindViewById<Button>(Resource.Id.playlist_btnNew);
_btnShuffle.Click += BtnShuffleOnClick;

_listView = FindViewById<ListView>(Resource.Id.playlist_listView);
_listView = FindViewById<CustomListView>(Resource.Id.playlist_listView);
_listAdapter = new PlaylistListAdapter(this, _listView, new Playlist());
_listView.SetAdapter(_listAdapter);
_listView.ItemClick += ListViewOnItemClick;
_listView.ItemLongClick += ListViewOnItemLongClick;

// Save the source activity type for later (for providing Up navigation)
_sourceActivityType = Intent.GetStringExtra("sourceActivity");

// Since the onViewReady action could not be added to an intent, tell the NavMgr the view is ready
((AndroidNavigationManager)_navigationManager).SetPlaylistActivityInstance(this);
}

public override void OnAttachedToWindow()
{
Console.WriteLine("PlaylistActivity - OnAttachedToWindow");
var window = this.Window;
window.AddFlags(WindowManagerFlags.ShowWhenLocked);
window.SetWindowAnimations(0);
}

private void BtnNewOnClick(object sender, EventArgs eventArgs)
{
OnNewPlaylist();
Expand Down Expand Up @@ -130,8 +143,9 @@ public override bool OnOptionsItemSelected(IMenuItem item)
switch (item.ItemId)
{
case global::Android.Resource.Id.Home:
var intent = new Intent(this, typeof (MainActivity));
intent.AddFlags(ActivityFlags.ClearTop | ActivityFlags.SingleTop);
var type = Type.GetType(_sourceActivityType);
var intent = new Intent(this, type);
intent.AddFlags(ActivityFlags.ClearTop | ActivityFlags.SingleTop);
this.StartActivity(intent);
this.Finish();
return true;
Expand Down
44 changes: 37 additions & 7 deletions MPfm/MPfm.Android/Classes/Adapters/PlaylistListAdapter.cs
Expand Up @@ -16,30 +16,27 @@
// along with MPfm. If not, see <http://www.gnu.org/licenses/>.

using System;
using System.Collections.Generic;
using Android.App;
using Android.Graphics;
using Android.Views;
using Android.Views.Animations;
using Android.Widget;
using MPfm.Library.Objects;
using MPfm.Sound.AudioFiles;
using MPfm.Sound.Playlists;
using org.sessionsapp.android;

namespace MPfm.Android.Classes.Adapters
{
public class PlaylistListAdapter : BaseAdapter<AudioFile>, View.IOnClickListener
public class PlaylistListAdapter : BaseAdapter<AudioFile>, View.IOnClickListener, View.IOnTouchListener
{
readonly PlaylistActivity _context;
readonly ListView _listView;
readonly CustomListView _listView;
Playlist _playlist;
int _nowPlayingRowPosition;
int _editingRowPosition;
Guid _nowPlayingAudioFileId;

public bool IsEditingRow { get; private set; }

public PlaylistListAdapter(PlaylistActivity context, ListView listView, Playlist playlist)
public PlaylistListAdapter(PlaylistActivity context, CustomListView listView, Playlist playlist)
{
_context = context;
_listView = listView;
Expand Down Expand Up @@ -77,15 +74,24 @@ public override View GetView(int position, View convertView, ViewGroup parent)
if (item == null)
return view;

view.Tag = position;
//view.SetOnTouchListener(this);

var index = view.FindViewById<TextView>(Resource.Id.playlistCell_lblIndex);
var title = view.FindViewById<TextView>(Resource.Id.playlistCell_lblTitle);
var subtitle = view.FindViewById<TextView>(Resource.Id.playlistCell_lblSubtitle);
var imageNowPlaying = view.FindViewById<ImageView>(Resource.Id.playlistCell_imageNowPlaying);

//index.Text = item.AudioFile.TrackNumber.ToString();
index.Text = (position+1).ToString();
title.Text = item.AudioFile.ArtistName + " / " + item.AudioFile.Title;
subtitle.Text = item.AudioFile.Length;

if (item.AudioFile != null && item.AudioFile.Id == _nowPlayingAudioFileId)
imageNowPlaying.Visibility = ViewStates.Visible;
else
imageNowPlaying.Visibility = ViewStates.Gone;

return view;
}

Expand Down Expand Up @@ -207,5 +213,29 @@ public void OnClick(View v)
break;
}
}

public bool OnTouch(View v, MotionEvent e)
{
//Console.WriteLine("PlaylistListAdapter - OnTouch - action: {0} buttonState: {1} downTime: {2} eventTime: {3} x: {4} y: {5}", e.Action, e.ButtonState, e.DownTime, e.EventTime, e.GetX(), e.GetY());

//float x = e.GetX();
//float y = e.GetY();

//// Keep cancel on top because the flag can contain both move and cancel.
//if (e.Action.HasFlag(MotionEventActions.Cancel))
//{
// Console.WriteLine("PlaylistListAdapter - OnTouch - Cancel - (x,y): ({0},{1})", x, y);
// _listView.IsScrollable = true;
//}
//else if (e.Action.HasFlag(MotionEventActions.Move))
//{
// Console.WriteLine("PlaylistListAdapter - OnTouch - Move - (x,y): ({0},{1})", x, y);
// _listView.IsScrollable = false;
//}

////Console.WriteLine("PlaylistListAdapter - OnTouch - Current cell - height: {0} - position: {1}", v.Height, (int)v.Tag);

return true;
}
}
}
154 changes: 154 additions & 0 deletions MPfm/MPfm.Android/Classes/Controls/CustomListView.cs
@@ -0,0 +1,154 @@
// Copyright © 2011-2013 Yanick Castonguay
//
// This file is part of MPfm.
//
// MPfm is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// MPfm is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with MPfm. If not, see <http://www.gnu.org/licenses/>.

using System;
using Android.Content;
using Android.Graphics;
using Android.Runtime;
using Android.Util;
using Android.Views;
using Android.Widget;

namespace org.sessionsapp.android
{
/// <summary>
/// This custom list view is based on the Android list view but adds a few things such as the IsScrollable property and the ability to change row order
/// (because Google is clearly too lazy to do anything like that).
/// </summary>
public class CustomListView : ListView
{
public bool CanItemsBeMoved { get; set; }
public bool IsScrollable { get; set; }
public bool IsMovingItem { get; private set; }

protected CustomListView(IntPtr javaReference, JniHandleOwnership transfer) : base(javaReference, transfer)
{
Initialize();
}

public CustomListView(Context context) : base(context)
{
Initialize();
}

public CustomListView(Context context, IAttributeSet attrs) : base(context, attrs)
{
Initialize();
}

public CustomListView(Context context, IAttributeSet attrs, int defStyle) : base(context, attrs, defStyle)
{
Initialize();
}

private void Initialize()
{
IsScrollable = true;
CanItemsBeMoved = true;
IsMovingItem = false;
}

public override bool DispatchTouchEvent(MotionEvent e)
{
//Console.WriteLine("CustomListView - DispatchTouchEvent - action: {0} buttonState: {1} downTime: {2} eventTime: {3} x,y: ({4},{5}) width: {6} density: {7} canItemsBeMoved: {8} isMovingItem: {9} isScrollable: {10}", e.Action, e.ButtonState, e.DownTime, e.EventTime, e.GetX(), e.GetY(), Width, Resources.DisplayMetrics.Density, CanItemsBeMoved, IsMovingItem, IsScrollable);
Console.WriteLine("CustomListView - DispatchTouchEvent - action: {0} x,y: ({1},{2})", e.Action, e.GetX(), e.GetY());

float density = Resources.DisplayMetrics.Density;
float x = e.GetX();
float y = e.GetY();

if (CanItemsBeMoved && !IsMovingItem && x >= Width - 48 * density)
{
// The user is trying to move an item using the right hand 'button'.
Console.WriteLine("CustomListView - DispatchTouchEvent - Starting to move item...");
View viewItemMove = GetChildAtPosition(x, y);
if (viewItemMove != null)
{
IsMovingItem = true;
IsScrollable = false;
int tag = -1;
if (viewItemMove.Tag != null)
tag = (int)viewItemMove.Tag;

Console.WriteLine("CustomListView - DispatchTouchEvent - Found moving item! tag: {0}", tag);
}
else
{
Console.WriteLine("CustomListView - DispatchTouchEvent - Did NOT find moving item :-(");
}
}

// Keep cancel on top because the flag can contain both move and cancel.
// if (e.Action.HasFlag(MotionEventActions.Cancel)) // This was cancel when using OnTouchListener on a child view
if(e.Action.HasFlag(MotionEventActions.Up))
{
//Console.WriteLine("CustomListView - DispatchTouchEvent - Up - (x,y): ({0},{1})", x, y);
Console.WriteLine("CustomListView - DispatchTouchEvent - CANCELLING MOVE...");
IsMovingItem = false;
IsScrollable = true;
}
else if (e.Action.HasFlag(MotionEventActions.Move))
{
// Block scroll
if(!IsScrollable)
return true;
}

// Try to find the item over the finger
View view = GetChildAtPosition(x, y);
if (view != null)
{
int tag = -1;
if (view.Tag != null)
tag = (int)view.Tag;

Console.WriteLine("CustomListView - DispatchTouchEvent - Found finger over view! tag: {0}", tag);
}
else
{
Console.WriteLine("CustomListView - DispatchTouchEvent - Did NOT find finger over view :-(");
}

return base.DispatchTouchEvent(e);
}

private View GetChildAtPosition(float x, float y)
{
View returnView = null;
int lastIndex = LastVisiblePosition - FirstVisiblePosition;
for (int a = 0; a < lastIndex; a++)
{
View view = GetChildAt(a);
if (view != null)
{
Rect rect = new Rect();
view.GetHitRect(rect);
bool isOverItem = y >= rect.Top && y <= rect.Bottom;
//Console.WriteLine("CustomListView - GetChildAtPosition - Finding rects - position: {0} hitRect(x,y): ({1},{2})", a, rect.Left, rect.Top);
if (isOverItem)
{
Console.WriteLine("CustomListView - GetChildAtPosition - FOUND CHILD - position: {0} hitRect(x,y): ({1},{2})", a, rect.Left, rect.Top);
returnView = view;
break;
}
}
}

return returnView;
}
}
}
15 changes: 7 additions & 8 deletions MPfm/MPfm.Android/Classes/Navigation/AndroidNavigationManager.cs
Expand Up @@ -244,9 +244,15 @@ protected override void CreateMarkerDetailsViewInternal(IBaseView sourceView, Ac
StartActivity(activity, typeof(MarkerDetailsActivity));
}

protected override void CreatePlaylistViewInternal(IBaseView sourceView, Action<IBaseView> onViewReady)
{
_onPlaylistViewReady = onViewReady;
var activity = GetActivityFromView(sourceView);
StartActivity(activity, typeof(PlaylistActivity));
}

protected override void CreateSyncViewInternal(Action<IBaseView> onViewReady)
{
// TODO: Add source view
_onSyncViewReady = onViewReady;
var intent = new Intent(MainActivity, typeof(SyncActivity));
MainActivity.StartActivity(intent);
Expand All @@ -273,13 +279,6 @@ protected override void CreateSyncDownloadViewInternal(Action<IBaseView> onViewR
MainActivity.StartActivity(intent);
}

protected override void CreatePlaylistViewInternal(Action<IBaseView> onViewReady)
{
_onPlaylistViewReady = onViewReady;
var intent = new Intent(MainActivity, typeof(PlaylistActivity));
MainActivity.StartActivity(intent);
}

public void SetAboutActivityInstance(AboutActivity activity)
{
if (_onAboutViewReady != null)
Expand Down
20 changes: 7 additions & 13 deletions MPfm/MPfm.Android/Classes/Services/NotificationService.cs
Expand Up @@ -92,7 +92,6 @@ public override StartCommandResult OnStartCommand(Intent intent, StartCommandFla
var notificationManager = (NotificationManager)ApplicationContext.GetSystemService(NotificationService);
notificationManager.Cancel(1);
StopSelf();

}

return StartCommandResult.NotSticky;
Expand Down Expand Up @@ -149,27 +148,22 @@ private Notification CreateNotificationView()
.SetSmallIcon(Resource.Drawable.Icon)
.Build();

// Use the big notification style for Android 4.1+; use the standard notification style for Android 4.0.3
// Use the big notification style for Android 4.1+;
//#if __ANDROID_16__
if (((int) global::Android.OS.Build.VERSION.SdkInt) >= 16)
{
Console.WriteLine("NotificationService - Android 4.1+ detected; using Big View style for notification");
Console.WriteLine("NotificationService - Android 4.1+ detected; adding Big View style for notification");
RemoteViews viewBigNotificationPlayer = new RemoteViews(ApplicationContext.PackageName, Resource.Layout.BigNotificationPlayer);
viewBigNotificationPlayer.SetTextViewText(Resource.Id.bigNotificationPlayer_lblArtistName, "Hello World!");
notification.BigContentView = viewBigNotificationPlayer;
}
//#else
else
{
Console.WriteLine("NotificationService - Android 4.0.3+ (<4.1) detected; using standard style for notification");
RemoteViews viewNotificationPlayer = new RemoteViews(ApplicationContext.PackageName, Resource.Layout.NotificationPlayer);
viewNotificationPlayer.SetTextViewText(Resource.Id.notificationPlayer_lblTitle, "Hello World!");
notification.ContentView = viewNotificationPlayer;
}
//#endif

Console.WriteLine("NotificationService - Android 4.0.3+ detected; adding standard style for notification");
RemoteViews viewNotificationPlayer = new RemoteViews(ApplicationContext.PackageName, Resource.Layout.NotificationPlayer);
notification.ContentView = viewNotificationPlayer;

_notification = notification;

// Create intents for buttons
Intent intentPlayPause = new Intent(this, typeof(NotificationService));
intentPlayPause.SetAction(SessionsWidgetActions.SessionsWidgetPlayPause.ToString());
PendingIntent pendingIntentPlayPause = PendingIntent.GetService(this, 0, intentPlayPause, PendingIntentFlags.UpdateCurrent);
Expand Down
5 changes: 5 additions & 0 deletions MPfm/MPfm.Android/MPfm.Android.csproj
Expand Up @@ -88,6 +88,7 @@
<Compile Include="Classes\Cache\BitmapWorkerTask.cs" />
<Compile Include="Classes\Cache\AsyncBitmapDrawable.cs" />
<Compile Include="Classes\Clients\MyWebViewClient.cs" />
<Compile Include="Classes\Controls\CustomListView.cs" />
<Compile Include="Classes\Controls\SquareImageView.cs" />
<Compile Include="Classes\Controls\EqualizerPresetGraphView.cs" />
<Compile Include="Classes\Controls\OutputMeterView.cs" />
Expand Down Expand Up @@ -499,6 +500,10 @@
<AndroidResource Include="Resources\Anim\flipper_changetab_in.xml">
<SubType>Designer</SubType>
</AndroidResource>
<AndroidResource Include="Resources\drawable-hdpi\icon_move.png" />
<AndroidResource Include="Resources\drawable-mdpi\icon_move.png" />
<AndroidResource Include="Resources\drawable-xhdpi\icon_move.png" />
<AndroidResource Include="Resources\drawable-xxhdpi\icon_move.png" />
</ItemGroup>
<ItemGroup>
<Folder Include="Lib\armeabi\" />
Expand Down

0 comments on commit b09686c

Please sign in to comment.