From 157a6a86a46369f95548bad6c8890927f0a3323c Mon Sep 17 00:00:00 2001 From: animal Date: Tue, 29 Jan 2013 04:16:58 +0000 Subject: [PATCH] MPfm Windows: Updated WinForms project after major namespace refactoring in one of the last check-ins. Library: Added a second implementation of Gateway, for Mono.Data.Sqlite. Useful for Android. Android: Added Update Library dialog, which works very well so far. NavigationManager: Updated implementation for Android. Related to issue #406. git-svn-id: http://hamster-svn/svn/repos/base@687 765c1f7c-9fb8-954f-9ff8-dd0915cb3117 --- .../Classes/Activities/BaseActivity.cs | 18 + .../Classes/Activities/MainActivity.cs | 239 +- .../Classes/Activities/SplashActivity.cs | 52 - .../Classes/Adapters/TabPagerAdapter.cs | 5 + .../Classes/AndroidNavigationManager.cs | 8 + .../Classes/Fragments/BaseFragment.cs | 11 + .../Fragments/UpdateLibraryFragment.cs | 29 + .../Classes/Objects/ApplicationState.cs | 7 + .../Classes/Objects/GenericListItem.cs | 6 - .../current/MPfm.Android/MPfm.Android.csproj | 16 +- .../MPfm.Android/Resources/Anim/fade_in.xml | 4 + .../MPfm.Android/Resources/Anim/fade_out.xml | 4 + .../Layout/Fragment_UpdateLibrary.axml | 35 + .../Resources/Layout/GenericCell.axml | 4 +- .../MPfm.Android/Resources/Layout/Splash.axml | 16 + .../MPfm.Android/Resources/Menu/main_menu.xml | 5 +- .../Resources/Resource.Designer.cs | 170 +- .../MPfm.Android/Resources/Values/Styles.xml | 24 +- .../MPfm.Library/Database/DatabaseFacade.cs | 1013 +++++++ .../{Gateway => Database}/IMPfmGateway.cs | 0 .../Database/Interfaces/IDatabaseFacade.cs | 89 + .../Interfaces}/ISQLiteGateway.cs | 3 +- .../{Gateway => Database}/MPfmGateway.cs | 0 .../Database/MonoSQLiteGateway.cs | 778 ++++++ .../{Gateway => Database}/SQLiteGateway.cs | 19 +- .../branches/current/MPfm.Library/ILibrary.cs | 7 +- .../MPfm.Library/Lib/AsyncCtpLibrary.dll | Bin 83736 -> 0 bytes .../MPfm.Library/Lib/AsyncCtpLibrary.xml | 2341 ----------------- .../MPfm.Library/Lib/System.Reactive.dll | Bin 397120 -> 0 bytes .../current/MPfm.Library/Lib/taglib-sharp.dll | Bin 435200 -> 0 bytes MPfm/branches/current/MPfm.Library/Library.cs | 178 +- .../MPfm.Library/MPfm.Library.Android.csproj | 14 +- .../MPfm.MVP/Bootstrapper/Bootstrapper.cs | 13 +- .../MPfm.MVP/Helpers/ConfigurationHelper.cs | 8 +- .../current/MPfm.MVP/NavigationManager.cs | 152 +- .../MPfm.MVP/Presenters/MainPresenter.cs | 2 +- .../MPfm.MVP/Presenters/PlayerPresenter.cs | 16 +- .../MPfm.MVP/Presenters/SplashPresenter.cs | 4 +- .../Presenters/UpdateLibraryPresenter.cs | 23 +- .../Services/InitializationService.cs | 8 +- .../MPfm.MVP/Services/LibraryService.cs | 7 +- .../MPfm.MVP/Services/UpdateLibraryService.cs | 20 +- .../MPfm.MVP/Views/IUpdateLibraryView.cs | 9 +- .../MPfm.Sound/AudioFiles/AudioFile.cs | 2 + MPfm/branches/current/MPfm.Sound/PeakFile.cs | 6 + 45 files changed, 2595 insertions(+), 2770 deletions(-) create mode 100644 MPfm/branches/current/MPfm.Android/Classes/Activities/BaseActivity.cs delete mode 100644 MPfm/branches/current/MPfm.Android/Classes/Activities/SplashActivity.cs create mode 100644 MPfm/branches/current/MPfm.Android/Classes/AndroidNavigationManager.cs create mode 100644 MPfm/branches/current/MPfm.Android/Classes/Fragments/BaseFragment.cs create mode 100644 MPfm/branches/current/MPfm.Android/Classes/Fragments/UpdateLibraryFragment.cs create mode 100644 MPfm/branches/current/MPfm.Android/Classes/Objects/ApplicationState.cs create mode 100644 MPfm/branches/current/MPfm.Android/Resources/Anim/fade_in.xml create mode 100644 MPfm/branches/current/MPfm.Android/Resources/Anim/fade_out.xml create mode 100644 MPfm/branches/current/MPfm.Android/Resources/Layout/Fragment_UpdateLibrary.axml create mode 100644 MPfm/branches/current/MPfm.Android/Resources/Layout/Splash.axml create mode 100644 MPfm/branches/current/MPfm.Library/Database/DatabaseFacade.cs rename MPfm/branches/current/MPfm.Library/{Gateway => Database}/IMPfmGateway.cs (100%) create mode 100644 MPfm/branches/current/MPfm.Library/Database/Interfaces/IDatabaseFacade.cs rename MPfm/branches/current/MPfm.Library/{Gateway => Database/Interfaces}/ISQLiteGateway.cs (97%) rename MPfm/branches/current/MPfm.Library/{Gateway => Database}/MPfmGateway.cs (100%) create mode 100644 MPfm/branches/current/MPfm.Library/Database/MonoSQLiteGateway.cs rename MPfm/branches/current/MPfm.Library/{Gateway => Database}/SQLiteGateway.cs (99%) delete mode 100644 MPfm/branches/current/MPfm.Library/Lib/AsyncCtpLibrary.dll delete mode 100644 MPfm/branches/current/MPfm.Library/Lib/AsyncCtpLibrary.xml delete mode 100644 MPfm/branches/current/MPfm.Library/Lib/System.Reactive.dll delete mode 100644 MPfm/branches/current/MPfm.Library/Lib/taglib-sharp.dll diff --git a/MPfm/branches/current/MPfm.Android/Classes/Activities/BaseActivity.cs b/MPfm/branches/current/MPfm.Android/Classes/Activities/BaseActivity.cs new file mode 100644 index 00000000..5921cbce --- /dev/null +++ b/MPfm/branches/current/MPfm.Android/Classes/Activities/BaseActivity.cs @@ -0,0 +1,18 @@ +using System; +using Android.App; +using MPfm.MVP.Views; + +namespace MPfm.Android +{ + [Activity(Icon = "@drawable/icon")] + public class BaseActivity : Activity, IBaseView + { + public Action OnViewDestroy { get; set; } + + public void ShowView(bool shown) + { + // Ignore on Android + } + } +} + diff --git a/MPfm/branches/current/MPfm.Android/Classes/Activities/MainActivity.cs b/MPfm/branches/current/MPfm.Android/Classes/Activities/MainActivity.cs index 84b0e42c..6557cfdb 100644 --- a/MPfm/branches/current/MPfm.Android/Classes/Activities/MainActivity.cs +++ b/MPfm/branches/current/MPfm.Android/Classes/Activities/MainActivity.cs @@ -1,61 +1,109 @@ using System; +using System.Collections.Generic; using Android.App; +using Android.Content.PM; using Android.Runtime; using Android.Support.V4.View; using Android.Views; using Android.OS; +using Android.Widget; +using MPfm.Android.Classes; using MPfm.Android.Classes.Adapters; using MPfm.Android.Classes.Fragments; using MPfm.Android.Classes.Listeners; +using MPfm.Android.Classes.Objects; +using MPfm.Library.UpdateLibrary; +using MPfm.MVP.Models; +using MPfm.MVP.Views; +using Environment = Android.OS.Environment; namespace MPfm.Android { - [Activity(Icon = "@drawable/icon")] - public class MainActivity : Activity + [Activity(MainLauncher = true, NoHistory = true, ScreenOrientation = ScreenOrientation.Portrait, Theme = "@style/MyAppTheme")] + public class MainActivity : BaseActivity, ISplashView, IUpdateLibraryView, View.IOnClickListener { - //NavigationManager navigationManager; private ViewPager _viewPager; private TabPagerAdapter _tabPagerAdapter; + private Dialog _splashDialog; + private Dialog _updateLibraryDialog; + private AndroidNavigationManager _navigationManager; + private Button _updateLibraryDialog_button; + private TextView _updateLibraryDialog_lblTitle; + private TextView _updateLibraryDialog_lblSubtitle; protected override void OnCreate(Bundle bundle) { base.OnCreate(bundle); + // Get application state + ApplicationState state = (ApplicationState) LastNonConfigurationInstance; + if (state != null) + { + // Restore state here + } + + // Load navigation manager and other important stuff before showing splash screen + _navigationManager = new AndroidNavigationManager(); RequestWindowFeature(WindowFeatures.ActionBar); + //RequestWindowFeature(WindowFeatures.Progress); SetContentView(Resource.Layout.Main); ActionBar.NavigationMode = ActionBarNavigationMode.Tabs; - - _viewPager = FindViewById(Resource.Id.main_pager); - _tabPagerAdapter = new TabPagerAdapter(FragmentManager, _viewPager, ActionBar); - _viewPager.Adapter = _tabPagerAdapter; - _viewPager.SetOnPageChangeListener(_tabPagerAdapter); - - var playerTab = ActionBar.NewTab(); - playerTab.SetTabListener(_tabPagerAdapter); - playerTab.SetText("Player"); - ActionBar.AddTab(playerTab); - var playlistsTab = ActionBar.NewTab(); - playlistsTab.SetTabListener(_tabPagerAdapter); - playlistsTab.SetText("Playlists"); - ActionBar.AddTab(playlistsTab); - var artistsTab = ActionBar.NewTab(); - artistsTab.SetTabListener(_tabPagerAdapter); - artistsTab.SetText("Artists"); - ActionBar.AddTab(artistsTab); - var albumsTab = ActionBar.NewTab(); - albumsTab.SetTabListener(_tabPagerAdapter); - albumsTab.SetText("Albums"); - ActionBar.AddTab(albumsTab); - var songsTab = ActionBar.NewTab(); - songsTab.SetTabListener(_tabPagerAdapter); - songsTab.SetText("Songs"); - ActionBar.AddTab(songsTab); - - // Create and start navigation manager - //navigationManager = Bootstrapper.GetContainer().Resolve(); - //navigationManager.Start(); - - //button.Click += delegate { button.Text = string.Format("{0} clicks!", count++); }; + //SetProgressBarVisibility(true); + //SetProgress(5000); + } + + protected override void OnStart() + { + base.OnStart(); + + // Bind this activity to splash and update library views + _navigationManager.BindSplashView(this, ContinueInitialize); + _navigationManager.BindUpdateLibraryView(this); + + // Show splash screen; then bind this activity to the Splash presenter + ShowSplashScreen(); + } + + private void ContinueInitialize() + { + RunOnUiThread(() => + { + // Stuff has finished loading; load layout + _viewPager = FindViewById(Resource.Id.main_pager); + _tabPagerAdapter = new TabPagerAdapter(FragmentManager, _viewPager, ActionBar); + _viewPager.Adapter = _tabPagerAdapter; + _viewPager.SetOnPageChangeListener(_tabPagerAdapter); + + var playerTab = ActionBar.NewTab(); + playerTab.SetTabListener(_tabPagerAdapter); + playerTab.SetText("Player"); + ActionBar.AddTab(playerTab); + var playlistsTab = ActionBar.NewTab(); + playlistsTab.SetTabListener(_tabPagerAdapter); + playlistsTab.SetText("Playlists"); + ActionBar.AddTab(playlistsTab); + var artistsTab = ActionBar.NewTab(); + artistsTab.SetTabListener(_tabPagerAdapter); + artistsTab.SetText("Artists"); + ActionBar.AddTab(artistsTab); + var albumsTab = ActionBar.NewTab(); + albumsTab.SetTabListener(_tabPagerAdapter); + albumsTab.SetText("Albums"); + ActionBar.AddTab(albumsTab); + var songsTab = ActionBar.NewTab(); + songsTab.SetTabListener(_tabPagerAdapter); + songsTab.SetText("Songs"); + ActionBar.AddTab(songsTab); + + RemoveSplashScreen(); + }); + } + + public override Java.Lang.Object OnRetainNonConfigurationInstance() + { + // Save stuff here + ApplicationState state = new ApplicationState(); + return state; } public override bool OnCreateOptionsMenu(IMenu menu) @@ -67,8 +115,127 @@ public override bool OnCreateOptionsMenu(IMenu menu) public override bool OnOptionsItemSelected(IMenuItem menuItem) { string text = menuItem.TitleFormatted.ToString(); + + if (text.ToUpper() == "EFFECTS") + { + ProgressDialog progressDialog = ProgressDialog.Show(this, "Update Library", "Updating library...", true); + } + else if (text.ToUpper() == "UPDATE LIBRARY") + { + ShowUpdateLibrary(); + } + else if (text.ToUpper() == "SETTINGS") + { + // Seperate activity? + } + else if (text.ToUpper() == "ABOUT MPFM") + { + ShowSplashScreen(); + } return base.OnOptionsItemSelected(menuItem); } + + private void ShowSplashScreen() + { + _splashDialog = new Dialog(this, Resource.Style.SplashTheme); + _splashDialog.SetContentView(Resource.Layout.Splash); + _splashDialog.SetCancelable(false); + _splashDialog.Show(); + } + + private void RemoveSplashScreen() + { + if (_splashDialog != null) + { + _splashDialog.Dismiss(); + _splashDialog = null; + } + } + + private void ShowUpdateLibrary() + { + // Configure dialog for Update Library + _updateLibraryDialog = new Dialog(this, Resource.Style.UpdateLibraryTheme); + _updateLibraryDialog.SetContentView(Resource.Layout.Fragment_UpdateLibrary); + _updateLibraryDialog.SetCancelable(false); + _updateLibraryDialog.SetTitle("Update Library"); + + // Get controls from dialog + _updateLibraryDialog_button = (Button)_updateLibraryDialog.FindViewById(Resource.Id.fragment_updateLibrary_button); + _updateLibraryDialog_button.SetOnClickListener(this); + _updateLibraryDialog_lblTitle = (TextView) _updateLibraryDialog.FindViewById(Resource.Id.fragment_updateLibrary_lblTitle); + _updateLibraryDialog_lblSubtitle = (TextView)_updateLibraryDialog.FindViewById(Resource.Id.fragment_updateLibrary_lblSubtitle); + _updateLibraryDialog.Show(); + + // Start update library process + string musicPath = Environment.GetExternalStoragePublicDirectory(Environment.DirectoryMusic).ToString(); + OnStartUpdateLibrary(UpdateLibraryMode.SpecificFolder, null, musicPath); + //OnStartUpdateLibrary(UpdateLibraryMode.WholeLibrary, null, null); + } + + private void RemoveUpdateLibrary() + { + if (_updateLibraryDialog != null) + { + _updateLibraryDialog.Dismiss(); + _updateLibraryDialog = null; + } + } + + #region ISplashView implementation + + public void RefreshStatus(string message) + { + RunOnUiThread(() => + { + TextView splashTextView = (TextView)_splashDialog.FindViewById(Resource.Id.splash_text); + splashTextView.Text = message; + }); + } + + public void InitDone() + { + } + + #endregion + + #region IUpdateLibraryView implementation + + public Action, string> OnStartUpdateLibrary { get; set; } + + public void RefreshStatus(UpdateLibraryEntity entity) + { + RunOnUiThread(() => + { + _updateLibraryDialog_lblTitle.Text = entity.Title; + _updateLibraryDialog_lblSubtitle.Text = entity.Subtitle; + }); + } + + public void AddToLog(string entry) + { + } + + public void ProcessEnded(bool canceled) + { + RunOnUiThread(() => + { + _updateLibraryDialog_lblTitle.Text = "Update successful."; + _updateLibraryDialog_lblSubtitle.Text = string.Empty; + _updateLibraryDialog_button.Text = "OK"; + }); + } + + #endregion + + public void OnClick(View v) + { + if (_updateLibraryDialog_button.Text == "Cancel") + { + // TODO: Cancel update + } + + RemoveUpdateLibrary(); + } } } - diff --git a/MPfm/branches/current/MPfm.Android/Classes/Activities/SplashActivity.cs b/MPfm/branches/current/MPfm.Android/Classes/Activities/SplashActivity.cs deleted file mode 100644 index 5cd03f1b..00000000 --- a/MPfm/branches/current/MPfm.Android/Classes/Activities/SplashActivity.cs +++ /dev/null @@ -1,52 +0,0 @@ -using Android.App; -using Android.Content.PM; -using Android.OS; - -namespace MPfm.Android -{ - [Activity(MainLauncher = true, NoHistory = true, ScreenOrientation = ScreenOrientation.Portrait, Theme = "@style/Theme.Splash")] - public class SplashActivity : Activity - { - //TextView textViewStatus; - - public SplashActivity() - { - } - - protected override void OnCreate(Bundle bundle) - { - base.OnCreate(bundle); - - //SetContentView(Resource.Layout.Splash); - //textViewStatus = FindViewById(Resource.Id.textViewStatus); - - StartActivity(typeof(MainActivity)); - } - - //public void ShowError(Exception ex) - //{ - // RunOnUiThread(() => - // { - // textViewStatus.Text = "Error: " + ex.Message; - // }); - //} - - //public void RefreshMessage(string message) - //{ - // RunOnUiThread(() => - // { - // textViewStatus.Text = message; - // }); - //} - - //public void InitializeDone() - //{ - // RunOnUiThread(() => - // { - // textViewStatus.Text = "Chargement complet."; - // StartActivity(typeof(MainActivity)); - // }); - //} - } -} - diff --git a/MPfm/branches/current/MPfm.Android/Classes/Adapters/TabPagerAdapter.cs b/MPfm/branches/current/MPfm.Android/Classes/Adapters/TabPagerAdapter.cs index 287ef988..feb76fe7 100644 --- a/MPfm/branches/current/MPfm.Android/Classes/Adapters/TabPagerAdapter.cs +++ b/MPfm/branches/current/MPfm.Android/Classes/Adapters/TabPagerAdapter.cs @@ -40,6 +40,11 @@ public void OnTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) { } + public override int GetItemPosition(Java.Lang.Object p0) + { + return base.GetItemPosition(p0); + } + public override Fragment GetItem(int p0) { return new GenericListFragment(); diff --git a/MPfm/branches/current/MPfm.Android/Classes/AndroidNavigationManager.cs b/MPfm/branches/current/MPfm.Android/Classes/AndroidNavigationManager.cs new file mode 100644 index 00000000..2b9641ef --- /dev/null +++ b/MPfm/branches/current/MPfm.Android/Classes/AndroidNavigationManager.cs @@ -0,0 +1,8 @@ +using MPfm.MVP; + +namespace MPfm.Android.Classes +{ + public class AndroidNavigationManager : NavigationManager + { + } +} \ No newline at end of file diff --git a/MPfm/branches/current/MPfm.Android/Classes/Fragments/BaseFragment.cs b/MPfm/branches/current/MPfm.Android/Classes/Fragments/BaseFragment.cs new file mode 100644 index 00000000..d5959df5 --- /dev/null +++ b/MPfm/branches/current/MPfm.Android/Classes/Fragments/BaseFragment.cs @@ -0,0 +1,11 @@ +using Android.App; +using Android.OS; +using Android.Views; + +namespace MPfm.Android.Classes.Fragments +{ + public class BaseFragment : Fragment + { + + } +} \ No newline at end of file diff --git a/MPfm/branches/current/MPfm.Android/Classes/Fragments/UpdateLibraryFragment.cs b/MPfm/branches/current/MPfm.Android/Classes/Fragments/UpdateLibraryFragment.cs new file mode 100644 index 00000000..7edbc209 --- /dev/null +++ b/MPfm/branches/current/MPfm.Android/Classes/Fragments/UpdateLibraryFragment.cs @@ -0,0 +1,29 @@ +using Android.App; +using Android.OS; +using Android.Views; +using Android.Widget; + +namespace MPfm.Android.Classes.Fragments +{ + public class UpdateLibraryFragment : Fragment, View.IOnClickListener + { + private View _view; + private ProgressBar _progressBar; + private TextView _lblSubtitle; + private TextView _lblTitle; + + public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) + { + _view = inflater.Inflate(Resource.Layout.Fragment_UpdateLibrary, container, false); + _progressBar = _view.FindViewById(Resource.Id.fragment_updateLibrary_progressBar); + _lblTitle = _view.FindViewById(Resource.Id.fragment_updateLibrary_lblTitle); + _lblSubtitle = _view.FindViewById(Resource.Id.fragment_updateLibrary_lblSubtitle); + return _view; + } + + public void OnClick(View v) + { + + } + } +} \ No newline at end of file diff --git a/MPfm/branches/current/MPfm.Android/Classes/Objects/ApplicationState.cs b/MPfm/branches/current/MPfm.Android/Classes/Objects/ApplicationState.cs new file mode 100644 index 00000000..3a286642 --- /dev/null +++ b/MPfm/branches/current/MPfm.Android/Classes/Objects/ApplicationState.cs @@ -0,0 +1,7 @@ +namespace MPfm.Android.Classes.Objects +{ + public class ApplicationState : Java.Lang.Object + { + public string Test { get; set; } + } +} \ No newline at end of file diff --git a/MPfm/branches/current/MPfm.Android/Classes/Objects/GenericListItem.cs b/MPfm/branches/current/MPfm.Android/Classes/Objects/GenericListItem.cs index 59bc3045..f02a79ca 100644 --- a/MPfm/branches/current/MPfm.Android/Classes/Objects/GenericListItem.cs +++ b/MPfm/branches/current/MPfm.Android/Classes/Objects/GenericListItem.cs @@ -1,9 +1,3 @@ -using System.Collections.Generic; -using Android.App; -using Android.Graphics; -using Android.Views; -using Android.Widget; - namespace MPfm.Android.Classes.Objects { public class GenericListItem diff --git a/MPfm/branches/current/MPfm.Android/MPfm.Android.csproj b/MPfm/branches/current/MPfm.Android/MPfm.Android.csproj index 822653ff..28e1b166 100644 --- a/MPfm/branches/current/MPfm.Android/MPfm.Android.csproj +++ b/MPfm/branches/current/MPfm.Android/MPfm.Android.csproj @@ -31,6 +31,8 @@ 4 True None + + True pdbonly @@ -56,16 +58,20 @@ - + + + + + @@ -87,6 +93,12 @@ Designer + + Designer + + + Designer + @@ -125,6 +137,8 @@ + + diff --git a/MPfm/branches/current/MPfm.Android/Resources/Anim/fade_in.xml b/MPfm/branches/current/MPfm.Android/Resources/Anim/fade_in.xml new file mode 100644 index 00000000..e8c93847 --- /dev/null +++ b/MPfm/branches/current/MPfm.Android/Resources/Anim/fade_in.xml @@ -0,0 +1,4 @@ + + \ No newline at end of file diff --git a/MPfm/branches/current/MPfm.Android/Resources/Anim/fade_out.xml b/MPfm/branches/current/MPfm.Android/Resources/Anim/fade_out.xml new file mode 100644 index 00000000..e844ca4d --- /dev/null +++ b/MPfm/branches/current/MPfm.Android/Resources/Anim/fade_out.xml @@ -0,0 +1,4 @@ + + \ No newline at end of file diff --git a/MPfm/branches/current/MPfm.Android/Resources/Layout/Fragment_UpdateLibrary.axml b/MPfm/branches/current/MPfm.Android/Resources/Layout/Fragment_UpdateLibrary.axml new file mode 100644 index 00000000..977b382b --- /dev/null +++ b/MPfm/branches/current/MPfm.Android/Resources/Layout/Fragment_UpdateLibrary.axml @@ -0,0 +1,35 @@ + + + + + + +