Skip to content

Commit

Permalink
Added new PlayerStatusView/Presenter.
Browse files Browse the repository at this point in the history
iOS: Updated MPfmNavigationController with "Now playing" indicator.

Related to issue #405.
  • Loading branch information
ycastonguay committed Apr 4, 2013
1 parent 7c70eb3 commit 6a9f2f0
Show file tree
Hide file tree
Showing 12 changed files with 233 additions and 9 deletions.
1 change: 1 addition & 0 deletions MPfm/MPfm.MVP/Bootstrap/Bootstrapper.cs
Expand Up @@ -72,6 +72,7 @@ static Bootstrapper()
container.Register<ITimeShiftingPresenter, TimeShiftingPresenter>().AsMultiInstance();
container.Register<IPitchShiftingPresenter, PitchShiftingPresenter>().AsMultiInstance();
container.Register<IPlayerMetadataPresenter, PlayerMetadataPresenter>().AsMultiInstance();
container.Register<IPlayerStatusPresenter, PlayerStatusPresenter>().AsMultiInstance();
}

/// <summary>
Expand Down
3 changes: 3 additions & 0 deletions MPfm/MPfm.MVP/MPfm.MVP.iOS.csproj
Expand Up @@ -292,5 +292,8 @@
<Compile Include="Presenters\LoopDetailsPresenter.cs" />
<Compile Include="Presenters\MarkerDetailsPresenter.cs" />
<Compile Include="Messages\MarkerUpdatedMessage.cs" />
<Compile Include="Views\IPlayerStatusView.cs" />
<Compile Include="Presenters\Interfaces\IPlayerStatusPresenter.cs" />
<Compile Include="Presenters\PlayerStatusPresenter.cs" />
</ItemGroup>
</Project>
29 changes: 29 additions & 0 deletions MPfm/MPfm.MVP/Presenters/Interfaces/IPlayerStatusPresenter.cs
@@ -0,0 +1,29 @@
// 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 MPfm.MVP.Models;
using MPfm.MVP.Views;

namespace MPfm.MVP.Presenters.Interfaces
{
/// <summary>
/// Player status presenter interface.
/// </summary>
public interface IPlayerStatusPresenter : IBasePresenter<IPlayerStatusView>
{
}
}
55 changes: 55 additions & 0 deletions MPfm/MPfm.MVP/Presenters/PlayerStatusPresenter.cs
@@ -0,0 +1,55 @@
// 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 MPfm.MVP.Messages;
using MPfm.MVP.Navigation;
using MPfm.MVP.Presenters.Interfaces;
using MPfm.MVP.Services.Interfaces;
using MPfm.MVP.Views;
using TinyMessenger;

namespace MPfm.MVP.Presenters
{
/// <summary>
/// Player status view presenter.
/// </summary>
public class PlayerStatusPresenter : BasePresenter<IPlayerStatusView>, IPlayerStatusPresenter
{
ITinyMessengerHub _messageHub;
IPlayerService _playerService;

public PlayerStatusPresenter(ITinyMessengerHub messageHub, IPlayerService playerService)
{
this._playerService = playerService;
this._messageHub = messageHub;
}

private void OnPlaylistIndexChanged(PlayerPlaylistIndexChangedMessage message)
{
//View.RefreshAudioFile(message.Data.AudioFileStarted);
}

public override void BindView(IPlayerMetadataView view)
{
// Subscribe to view actions
base.BindView(view);

_messageHub.Subscribe<PlayerPlaylistIndexChangedMessage>(OnPlaylistIndexChanged);
}
}
}

29 changes: 29 additions & 0 deletions MPfm/MPfm.MVP/Views/IPlayerStatusView.cs
@@ -0,0 +1,29 @@
// 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.Collections.Generic;
using MPfm.Sound.AudioFiles;

namespace MPfm.MVP.Views
{
/// <summary>
/// Player status view interface.
/// </summary>
public interface IPlayerStatusView : IBaseView
{
}
}
Expand Up @@ -41,7 +41,7 @@ public override void ViewDidLoad()
{
// Add gradient background
CAGradientLayer gradient = new CAGradientLayer();
gradient.Frame = this.View.Bounds;
gradient.Frame = this.View.Frame;
gradient.Colors = new MonoTouch.CoreGraphics.CGColor[2] { new CGColor(0.1f, 0.1f, 0.1f, 1), new CGColor(0.4f, 0.4f, 0.4f, 1) }; //[NSArray arrayWithObjects:(id)[[UIColor blackColor] CGColor], (id)[[UIColor whiteColor] CGColor], nil];
this.View.Layer.InsertSublayer(gradient, 0);

Expand Down
Expand Up @@ -67,14 +67,14 @@ public override void TouchesEnded(NSSet touches, UIEvent evt)
{
base.TouchesEnded(touches, evt);

CreateFadeTimer();
//CreateFadeTimer();
}

public override void TouchesCancelled(NSSet touches, UIEvent evt)
{
base.TouchesCancelled(touches, evt);

CreateFadeTimer();
//CreateFadeTimer();
}

private void CreateFadeTimer()
Expand Down
115 changes: 110 additions & 5 deletions MPfm/MPfm.iOS/Classes/Controls/MPfmNavigationController.cs
Expand Up @@ -19,24 +19,37 @@
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using MonoTouch.Foundation;
using MonoTouch.UIKit;
using MPfm.MVP.Bootstrap;
using MPfm.MVP.Messages;
using MPfm.MVP.Navigation;
using MonoTouch.CoreGraphics;
using MonoTouch.Foundation;
using MonoTouch.UIKit;
using TinyMessenger;
using MPfm.iOS.Classes.Controllers;
using MonoTouch.CoreAnimation;

namespace MPfm.iOS.Classes.Controls
{
[Register("MPfmNavigationController")]
public class MPfmNavigationController : UINavigationController
{
bool _isPlayerPlaying;
bool _isViewPlayer;
UILabel _lblTitle;
UILabel _lblSubtitle;
UIButton _btnBack;
UIButton _btnEffects;
UIButton _btnNowPlaying;
UIView _viewNowPlaying;
ITinyMessengerHub _messengerHub;
MobileNavigationTabType _tabType;

public MPfmNavigationController() : base()
public MPfmNavigationController(MobileNavigationTabType tabType) : base()
{
// TODO: Cannot bind this to IPlayerStatusView since there's multiple NavCtrl in the application...

this._tabType = tabType;
this.WeakDelegate = this;

_btnBack = new UIButton(UIButtonType.Custom);
Expand All @@ -49,9 +62,10 @@ public MPfmNavigationController() : base()
}
};

_btnEffects = new UIButton(UIButtonType.RoundedRect);
_btnEffects.Frame = new RectangleF(this.NavigationBar.Frame.Width - 4 - 36, 4, 36, 36);
_btnEffects = new UIButton(UIButtonType.Custom);
_btnEffects.Frame = new RectangleF(UIScreen.MainScreen.Bounds.Width - 4 - 36, 4, 36, 36);
_btnEffects.SetBackgroundImage(UIImage.FromBundle("Images/effects.png"), UIControlState.Normal);
_btnEffects.Alpha = 0;

_lblTitle = new UILabel(new RectangleF(50, 6, UIScreen.MainScreen.Bounds.Width - 120, 20));
_lblTitle.TextColor = UIColor.White;
Expand All @@ -68,15 +82,94 @@ public MPfmNavigationController() : base()
_lblSubtitle.TextAlignment = UITextAlignment.Left;
_lblSubtitle.Font = UIFont.FromName("HelveticaNeue-Light", 12);

_viewNowPlaying = new UIView(new RectangleF(UIScreen.MainScreen.Bounds.Width - 4 - 36, 4, 36, 36));
_viewNowPlaying.BackgroundColor = UIColor.Clear;
_viewNowPlaying.Alpha = 0;

_btnNowPlaying = new UIButton(UIButtonType.Custom);
_btnNowPlaying.Frame = new RectangleF(4, 4, 28, 28);
_btnNowPlaying.SetBackgroundImage(UIImage.FromBundle("Images/media.png"), UIControlState.Normal);
_btnNowPlaying.TouchUpInside += HandleButtonNowPlayingTouchUpInside;
_viewNowPlaying.AddSubview(_btnNowPlaying);

// Add gradient background to Now Playing view
CAGradientLayer gradient = new CAGradientLayer();
gradient.Frame = _viewNowPlaying.Bounds;
gradient.Colors = new MonoTouch.CoreGraphics.CGColor[2] { new CGColor(0.2f, 0.2f, 0.2f, 1), new CGColor(0.3f, 0.3f, 0.3f, 1) }; //[NSArray arrayWithObjects:(id)[[UIColor blackColor] CGColor], (id)[[UIColor whiteColor] CGColor], nil];
_viewNowPlaying.Layer.InsertSublayer(gradient, 0);

this.NavigationBar.AddSubview(_viewNowPlaying);
this.NavigationBar.AddSubview(_btnBack);
this.NavigationBar.AddSubview(_btnEffects);
this.NavigationBar.AddSubview(_lblTitle);
this.NavigationBar.AddSubview(_lblSubtitle);

// Instead of using a view/presenter, listen to messages from TinyMessenger
// (the NavCtrl is unique to iOS and shouldn't be created by the NavMgr in my opinion)
_messengerHub = Bootstrapper.GetContainer().Resolve<ITinyMessengerHub>();
_messengerHub.Subscribe<PlayerPlaylistIndexChangedMessage>((message) => {
// Display the "Now Playing" icon, but only if the current view isn't PlayerViewCtrl.
Console.WriteLine("NavCtrl (" + _tabType.ToString() + ") - PlayerPlaylistIndexChangedMessage");
UpdateNowPlayingView();
});
_messengerHub.Subscribe<PlayerStatusMessage>((message) => {
Console.WriteLine("NavCtrl (" + _tabType.ToString() + ") - PlayerStatusMessage - Status=" + message.Status.ToString());
if(message.Status == PlayerStatusType.Playing)
_isPlayerPlaying = true;
else
_isPlayerPlaying = false;
// TODO: Stop vinyl animation when player is paused
UpdateNowPlayingView();
});
}

private void HandleButtonNowPlayingTouchUpInside(object sender, EventArgs e)
{

}

private void UpdateNowPlayingView()
{
Console.WriteLine("NavCtrl (" + _tabType.ToString() + ") - UpdateNowPlayingView: isPlayerPlaying=" + _isPlayerPlaying.ToString() + " isViewPlayer=" + _isViewPlayer.ToString());
if(_isPlayerPlaying && !_isViewPlayer)
{
Console.WriteLine("NavCtrl - Showing Now Playing view...");
UIView.Animate(0.3f, () => {
_btnEffects.Frame = new RectangleF(UIScreen.MainScreen.Bounds.Width, 4, 36, 36);
_btnEffects.Alpha = 0;
_viewNowPlaying.Frame = new RectangleF(UIScreen.MainScreen.Bounds.Width - 4 - 36, 4, 36, 36);
_viewNowPlaying.Alpha = 1;
});
}
else if(_isViewPlayer)
{
UIView.Animate(0.3f, () => {
_btnEffects.Frame = new RectangleF(UIScreen.MainScreen.Bounds.Width - 4 - 36, 4, 36, 36);
_btnEffects.Alpha = 1;
_viewNowPlaying.Frame = new RectangleF(UIScreen.MainScreen.Bounds.Width, 4, 36, 36);
_viewNowPlaying.Alpha = 0;
});
}
}

[Export("navigationBar:shouldPushItem:")]
public bool ShouldPushItem(UINavigationItem item)
{
if(this.VisibleViewController is PlayerViewController)
{
// Hide Now Playing view
_isViewPlayer = true;
}
else
{
// Show Now Playing view
_isViewPlayer = false;
}
UpdateNowPlayingView();

if (ViewControllers.Length > 1)
{
UIView.Animate(0.25, () => {
Expand All @@ -93,6 +186,18 @@ public bool ShouldPushItem(UINavigationItem item)
[Export("navigationBar:shouldPopItem:")]
public bool ShouldPopItem(UINavigationItem item)
{
if(this.VisibleViewController is PlayerViewController)
{
// Hide Now Playing view
_isViewPlayer = true;
}
else
{
// Show Now Playing view
_isViewPlayer = false;
}
UpdateNowPlayingView();

if (ViewControllers.Length == 1)
{
UIView.Animate(0.25, () => {
Expand Down
2 changes: 1 addition & 1 deletion MPfm/MPfm.iOS/Classes/Delegates/AppDelegate.cs
Expand Up @@ -130,7 +130,7 @@ public void AddTab(MobileNavigationTabType type, string title, UIViewController
attr.TextShadowOffset = new UIOffset(1, 1);
// Create navigation controller
var navCtrl = new MPfmNavigationController();
var navCtrl = new MPfmNavigationController(type);
navCtrl.SetTitle(title, "");
//navCtrl.NavigationBar.BackgroundColor = UIColor.FromRGBA(0.5f, 1, 0.5f, 1);
navCtrl.NavigationBar.TintColor = UIColor.FromRGBA(0.2f, 0.2f, 0.2f, 1);
Expand Down
Binary file added MPfm/MPfm.iOS/Images/media.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added MPfm/MPfm.iOS/Images/media@2x.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions MPfm/MPfm.iOS/MPfm.iOS.csproj
Expand Up @@ -277,6 +277,8 @@
<BundleResource Include="Images\Buttons\previous_on%402x.png" />
<BundleResource Include="Images\Buttons\previous.png" />
<BundleResource Include="Images\Buttons\previous%402x.png" />
<BundleResource Include="Images\media.png" />
<BundleResource Include="Images\media%402x.png" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\MPfm.Core\MPfm.Core.iOS.csproj">
Expand Down

0 comments on commit 6a9f2f0

Please sign in to comment.