From c3ab1c8ecbc68f5534f442f325be2777956747a3 Mon Sep 17 00:00:00 2001 From: Tomasz Cielecki Date: Mon, 14 Oct 2019 09:14:38 +0200 Subject: [PATCH 01/22] Add analyzers --- AndHUD/AndHUD.csproj | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/AndHUD/AndHUD.csproj b/AndHUD/AndHUD.csproj index 79837c8..105aba6 100644 --- a/AndHUD/AndHUD.csproj +++ b/AndHUD/AndHUD.csproj @@ -8,10 +8,15 @@ - + + + + + + \ No newline at end of file From 06684cbd9a5d3784d5d0a32cc068f53c1da3ea5d Mon Sep 17 00:00:00 2001 From: Tomasz Cielecki Date: Mon, 14 Oct 2019 09:14:51 +0200 Subject: [PATCH 02/22] Remove weird self assignement --- AndHUD/ProgressWheel.cs | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/AndHUD/ProgressWheel.cs b/AndHUD/ProgressWheel.cs index 8c12474..a2e98c8 100644 --- a/AndHUD/ProgressWheel.cs +++ b/AndHUD/ProgressWheel.cs @@ -148,16 +148,6 @@ void SetupPaints() void SetupBounds() { - WheelPaddingTop = this.WheelPaddingTop; - WheelPaddingBottom = this.WheelPaddingBottom; - WheelPaddingLeft = this.WheelPaddingLeft; - WheelPaddingRight = this.WheelPaddingRight; - -// rectBounds = new RectF(WheelPaddingLeft, -// WheelPaddingTop, -// this.LayoutParameters.Width - WheelPaddingRight, -// this.LayoutParameters.Height - WheelPaddingBottom); -// circleBounds = new RectF(WheelPaddingLeft + BarWidth, WheelPaddingTop + BarWidth, this.LayoutParameters.Width - WheelPaddingRight - BarWidth, From 294c492eb125e2856eee658f7bec04898d5f7f22 Mon Sep 17 00:00:00 2001 From: Tomasz Cielecki Date: Mon, 14 Oct 2019 09:15:04 +0200 Subject: [PATCH 03/22] Throw exception if context is null --- AndHUD/AndHUD.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/AndHUD/AndHUD.cs b/AndHUD/AndHUD.cs index 4c00e1c..507b2e1 100644 --- a/AndHUD/AndHUD.cs +++ b/AndHUD/AndHUD.cs @@ -107,6 +107,9 @@ Drawable GetDrawable(Context context, int drawableResourceId) void showStatus (Context context, bool spinner, string status = null, MaskType maskType = MaskType.Black, TimeSpan? timeout = null, Action clickCallback = null, bool centered = true, Action cancelCallback = null, Action prepareDialogCallback = null, Action dialogShownCallback = null) { + if (context == null) + throw new ArgumentNullException(nameof(context)); + if (timeout == null) timeout = TimeSpan.Zero; From 28f8424cb584304f2a4031b374a83c9aa2abe62b Mon Sep 17 00:00:00 2001 From: Tomasz Cielecki Date: Tue, 15 Oct 2019 15:33:40 +0200 Subject: [PATCH 04/22] Add stylecop rules --- AndHUD.sln | 1 + stylecop.json | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 stylecop.json diff --git a/AndHUD.sln b/AndHUD.sln index 70b16e3..6d6b6be 100644 --- a/AndHUD.sln +++ b/AndHUD.sln @@ -16,6 +16,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SolutionItems", "SolutionIt Directory.build.targets = Directory.build.targets global.json = global.json README.md = README.md + stylecop.json = stylecop.json EndProjectSection EndProject Global diff --git a/stylecop.json b/stylecop.json new file mode 100644 index 0000000..324f4a9 --- /dev/null +++ b/stylecop.json @@ -0,0 +1,39 @@ +{ + "$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json", + "settings": { + "indentation": { + "useTabs": false, + "indentationSize": 4 + }, + "documentationRules": { + "documentExposedElements": true, + "documentInternalElements": false, + "documentPrivateElements": false, + "documentInterfaces": true, + "documentPrivateFields": false, + "documentationCulture": "en-US", + "variables": { + "licenseName": "Apache 2.0", + "licenseFile": "LICENSE" + }, + "xmlHeader": false + }, + "layoutRules": { + "newlineAtEndOfFile": "allow", + "allowConsecutiveUsings": true + }, + "maintainabilityRules": { + "topLevelTypes": [ + "class", + "interface", + "struct", + "enum", + "delegate" + ] + }, + "orderingRules": { + "usingDirectivesPlacement": "outsideNamespace", + "systemUsingDirectivesFirst": true + } + } +} From 0ecdd6e2c4fdddf8d2adc937a66332f5c5129843 Mon Sep 17 00:00:00 2001 From: Tomasz Cielecki Date: Tue, 15 Oct 2019 15:34:54 +0200 Subject: [PATCH 05/22] Add analyzers ruleset --- Directory.build.props | 2 + analyzers.ruleset | 283 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 285 insertions(+) create mode 100644 analyzers.ruleset diff --git a/Directory.build.props b/Directory.build.props index 97e0f66..d2e946f 100644 --- a/Directory.build.props +++ b/Directory.build.props @@ -19,6 +19,8 @@ 7.3 $(NoWarn);1591;1701;1702;1705;VSX1000;NU1603 + + $(MSBuildThisFileDirectory)analyzers.ruleset diff --git a/analyzers.ruleset b/analyzers.ruleset new file mode 100644 index 0000000..4761df9 --- /dev/null +++ b/analyzers.ruleset @@ -0,0 +1,283 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 9aca34380fcd1d11a7e622ade71d50048a8b33c9 Mon Sep 17 00:00:00 2001 From: Tomasz Cielecki Date: Tue, 15 Oct 2019 15:34:59 +0200 Subject: [PATCH 06/22] Fix urls --- Directory.build.props | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Directory.build.props b/Directory.build.props index d2e946f..730a0f7 100644 --- a/Directory.build.props +++ b/Directory.build.props @@ -2,15 +2,15 @@ Copyright (c) Redth Apache-2.0 - https://github.com/Redth/AndHUD - https://raw.githubusercontent.com/Redth/AndHUD/develop/icon.png + https://github.com/redth-org/AndHUD + https://raw.githubusercontent.com/redth-orgAndHUD/develop/icon.png Redth Redth Xamarin, Android, Progress, AndHUD, AndroidHUD - https://github.com/Redth/AndHUD/releases + https://github.com/redth-org/AndHUD/releases false - https://github.com/Redth/AndHUD + https://github.com/redth-org/AndHUD git $(AssemblyName) ($(TargetFramework)) en From 19322dcb6995591fe0291f716f7e9f3fc816f475 Mon Sep 17 00:00:00 2001 From: Tomasz Cielecki Date: Tue, 15 Oct 2019 15:35:15 +0200 Subject: [PATCH 07/22] Move packages to build props --- AndHUD/AndHUD.csproj | 11 +++-------- Directory.build.props | 11 +++++++++++ 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/AndHUD/AndHUD.csproj b/AndHUD/AndHUD.csproj index 105aba6..d0cb5c3 100644 --- a/AndHUD/AndHUD.csproj +++ b/AndHUD/AndHUD.csproj @@ -9,14 +9,9 @@ - - - + + + - - - - - \ No newline at end of file diff --git a/Directory.build.props b/Directory.build.props index 730a0f7..72890d8 100644 --- a/Directory.build.props +++ b/Directory.build.props @@ -44,5 +44,16 @@ true $(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb + + + + + + + + + + + \ No newline at end of file From 2f8c0458ae063f4fa6c58563b55f62301c34b7f5 Mon Sep 17 00:00:00 2001 From: Tomasz Cielecki Date: Tue, 15 Oct 2019 15:35:30 +0200 Subject: [PATCH 08/22] Add analyzers to sln --- AndHUD.sln | 1 + 1 file changed, 1 insertion(+) diff --git a/AndHUD.sln b/AndHUD.sln index 6d6b6be..a4bbdba 100644 --- a/AndHUD.sln +++ b/AndHUD.sln @@ -17,6 +17,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SolutionItems", "SolutionIt global.json = global.json README.md = README.md stylecop.json = stylecop.json + analyzers.ruleset = analyzers.ruleset EndProjectSection EndProject Global From c54d40801ac885f3e6e92f4e8817870d62f3941e Mon Sep 17 00:00:00 2001 From: Tomasz Cielecki Date: Tue, 15 Oct 2019 15:35:37 +0200 Subject: [PATCH 09/22] Update msbuild extras --- global.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/global.json b/global.json index e6e7cdb..80d84a2 100644 --- a/global.json +++ b/global.json @@ -1,5 +1,5 @@ { "msbuild-sdks": { - "MSBuild.Sdk.Extras": "2.0.43" + "MSBuild.Sdk.Extras": "2.0.54" } } \ No newline at end of file From 8ba58f1297e78dad5903d074007d314a8274fa1b Mon Sep 17 00:00:00 2001 From: Tomasz Cielecki Date: Tue, 15 Oct 2019 15:35:46 +0200 Subject: [PATCH 10/22] Fix trailing whitespace --- AndHUD/AndHUD.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/AndHUD/AndHUD.cs b/AndHUD/AndHUD.cs index 507b2e1..83eaae1 100644 --- a/AndHUD/AndHUD.cs +++ b/AndHUD/AndHUD.cs @@ -151,7 +151,7 @@ void showStatus (Context context, bool spinner, string status = null, MaskType m d.Window.Attributes = p; } - + return view; }, prepareDialogCallback, dialogShownCallback); @@ -168,7 +168,7 @@ void showStatus (Context context, bool spinner, string status = null, MaskType m } } - int DpToPx(Context context, int dp) + int DpToPx(Context context, int dp) { var displayMetrics = context.Resources.DisplayMetrics; return (int)TypedValue.ApplyDimension(ComplexUnitType.Dip, dp, displayMetrics); @@ -246,7 +246,7 @@ void showImage(Context context, Drawable image, string status = null, MaskType m if (maskType != MaskType.Black) view.SetBackgroundResource(Resource.Drawable.roundedbgdark); - + imageView?.SetImageDrawable(image); if (statusText != null) @@ -307,7 +307,7 @@ void SetupDialog(Context context, MaskType maskType, Action cancelCallback, Func dialog.SetContentView (customView); - dialog.SetCancelable (cancelCallback != null); + dialog.SetCancelable (cancelCallback != null); if (cancelCallback != null) dialog.CancelEvent += (sender, e) => cancelCallback(); @@ -346,7 +346,7 @@ void DismissCurrent(Context context = null) waitDismiss.Reset (); }; - + // First try the SynchronizationContext if (Application.SynchronizationContext != null) { @@ -396,7 +396,7 @@ bool IsAlive(Java.Lang.Object @object) if (activity.IsFinishing) return false; - if (Build.VERSION.SdkInt >= BuildVersionCodes.JellyBeanMr1 && + if (Build.VERSION.SdkInt >= BuildVersionCodes.JellyBeanMr1 && activity.IsDestroyed) return false; } From 26da711b09fc13f1426d1b3e3a0bf7a6faccc77e Mon Sep 17 00:00:00 2001 From: Tomasz Cielecki Date: Tue, 15 Oct 2019 15:40:28 +0200 Subject: [PATCH 11/22] Convert to spaces --- AndHUD/AndHUD.cs | 488 +++++++++++++++++++++++------------------------ AndHUD/XHUD.cs | 60 +++--- 2 files changed, 274 insertions(+), 274 deletions(-) diff --git a/AndHUD/AndHUD.cs b/AndHUD/AndHUD.cs index 83eaae1..acca6bf 100644 --- a/AndHUD/AndHUD.cs +++ b/AndHUD/AndHUD.cs @@ -13,83 +13,83 @@ namespace AndroidHUD { public class AndHUD - { - static AndHUD shared; - - public static AndHUD Shared - { - get - { - if (shared == null) - shared = new AndHUD (); - - return shared; - } - } - - public AndHUD() - { - } - - ManualResetEvent waitDismiss = new ManualResetEvent(false); - public Dialog CurrentDialog { get; private set; } - - ProgressWheel progressWheel = null; - TextView statusText = null; - ImageView imageView = null; - - object statusObj = null; - - readonly object dialogLock = new object(); - - - public void Show (Context context, string status = null, int progress = -1, MaskType maskType = MaskType.Black, TimeSpan? timeout = null, Action clickCallback = null, bool centered = true, Action cancelCallback = null, Action prepareDialogCallback = null, Action dialogShownCallback = null) - { - if (progress >= 0) - showProgress (context, progress, status, maskType, timeout, clickCallback, cancelCallback, prepareDialogCallback, dialogShownCallback); - else - showStatus (context, true, status, maskType, timeout, clickCallback, centered, cancelCallback, prepareDialogCallback, dialogShownCallback); - } - - public void ShowSuccess(Context context, string status = null, MaskType maskType = MaskType.Black, TimeSpan? timeout = null, Action clickCallback = null, Action cancelCallback = null, Action prepareDialogCallback = null, Action dialogShownCallback = null) - { - showImage (context, GetDrawable(context, Resource.Drawable.ic_successstatus), status, maskType, timeout, clickCallback, cancelCallback, prepareDialogCallback, dialogShownCallback); - } - - public void ShowError(Context context, string status = null, MaskType maskType = MaskType.Black, TimeSpan? timeout = null, Action clickCallback = null, Action cancelCallback = null, Action prepareDialogCallback = null, Action dialogShownCallback = null) - { - showImage (context, GetDrawable(context, Resource.Drawable.ic_errorstatus), status, maskType, timeout, clickCallback, cancelCallback, prepareDialogCallback, dialogShownCallback); - } - - public void ShowSuccessWithStatus(Context context, string status, MaskType maskType = MaskType.Black, TimeSpan? timeout = null, Action clickCallback = null, Action cancelCallback = null, Action prepareDialogCallback = null, Action dialogShownCallback = null) - { - showImage (context, GetDrawable(context, Resource.Drawable.ic_successstatus), status, maskType, timeout, clickCallback, cancelCallback, prepareDialogCallback, dialogShownCallback); - } - - public void ShowErrorWithStatus(Context context, string status, MaskType maskType = MaskType.Black, TimeSpan? timeout = null, Action clickCallback = null, Action cancelCallback = null, Action prepareDialogCallback = null, Action dialogShownCallback = null) - { - showImage (context, GetDrawable(context, Resource.Drawable.ic_errorstatus), status, maskType, timeout, clickCallback, cancelCallback, prepareDialogCallback, dialogShownCallback); - } - - public void ShowImage(Context context, int drawableResourceId, string status = null, MaskType maskType = MaskType.Black, TimeSpan? timeout = null, Action clickCallback = null, Action cancelCallback = null, Action prepareDialogCallback = null, Action dialogShownCallback = null) - { - showImage (context, GetDrawable(context, drawableResourceId), status, maskType, timeout, clickCallback, cancelCallback, prepareDialogCallback, dialogShownCallback); - } - - public void ShowImage(Context context, Drawable drawable, string status = null, MaskType maskType = MaskType.Black, TimeSpan? timeout = null, Action clickCallback = null, Action cancelCallback = null, Action prepareDialogCallback = null, Action dialogShownCallback = null) - { - showImage (context, drawable, status, maskType, timeout, clickCallback, cancelCallback, prepareDialogCallback, dialogShownCallback); - } - - public void ShowToast(Context context, string status, MaskType maskType = MaskType.Black, TimeSpan? timeout = null, bool centered = true, Action clickCallback = null, Action cancelCallback = null, Action prepareDialogCallback = null, Action dialogShownCallback = null) - { - showStatus (context, false, status, maskType, timeout, clickCallback, centered, cancelCallback, prepareDialogCallback, dialogShownCallback); - } - - public void Dismiss(Context context = null) - { - DismissCurrent (context); - } + { + static AndHUD shared; + + public static AndHUD Shared + { + get + { + if (shared == null) + shared = new AndHUD(); + + return shared; + } + } + + public AndHUD() + { + } + + ManualResetEvent waitDismiss = new ManualResetEvent(false); + public Dialog CurrentDialog { get; private set; } + + ProgressWheel progressWheel = null; + TextView statusText = null; + ImageView imageView = null; + + object statusObj = null; + + readonly object dialogLock = new object(); + + + public void Show (Context context, string status = null, int progress = -1, MaskType maskType = MaskType.Black, TimeSpan? timeout = null, Action clickCallback = null, bool centered = true, Action cancelCallback = null, Action prepareDialogCallback = null, Action dialogShownCallback = null) + { + if (progress >= 0) + showProgress(context, progress, status, maskType, timeout, clickCallback, cancelCallback, prepareDialogCallback, dialogShownCallback); + else + showStatus(context, true, status, maskType, timeout, clickCallback, centered, cancelCallback, prepareDialogCallback, dialogShownCallback); + } + + public void ShowSuccess(Context context, string status = null, MaskType maskType = MaskType.Black, TimeSpan? timeout = null, Action clickCallback = null, Action cancelCallback = null, Action prepareDialogCallback = null, Action dialogShownCallback = null) + { + showImage(context, GetDrawable(context, Resource.Drawable.ic_successstatus), status, maskType, timeout, clickCallback, cancelCallback, prepareDialogCallback, dialogShownCallback); + } + + public void ShowError(Context context, string status = null, MaskType maskType = MaskType.Black, TimeSpan? timeout = null, Action clickCallback = null, Action cancelCallback = null, Action prepareDialogCallback = null, Action dialogShownCallback = null) + { + showImage(context, GetDrawable(context, Resource.Drawable.ic_errorstatus), status, maskType, timeout, clickCallback, cancelCallback, prepareDialogCallback, dialogShownCallback); + } + + public void ShowSuccessWithStatus(Context context, string status, MaskType maskType = MaskType.Black, TimeSpan? timeout = null, Action clickCallback = null, Action cancelCallback = null, Action prepareDialogCallback = null, Action dialogShownCallback = null) + { + showImage(context, GetDrawable(context, Resource.Drawable.ic_successstatus), status, maskType, timeout, clickCallback, cancelCallback, prepareDialogCallback, dialogShownCallback); + } + + public void ShowErrorWithStatus(Context context, string status, MaskType maskType = MaskType.Black, TimeSpan? timeout = null, Action clickCallback = null, Action cancelCallback = null, Action prepareDialogCallback = null, Action dialogShownCallback = null) + { + showImage(context, GetDrawable(context, Resource.Drawable.ic_errorstatus), status, maskType, timeout, clickCallback, cancelCallback, prepareDialogCallback, dialogShownCallback); + } + + public void ShowImage(Context context, int drawableResourceId, string status = null, MaskType maskType = MaskType.Black, TimeSpan? timeout = null, Action clickCallback = null, Action cancelCallback = null, Action prepareDialogCallback = null, Action dialogShownCallback = null) + { + showImage(context, GetDrawable(context, drawableResourceId), status, maskType, timeout, clickCallback, cancelCallback, prepareDialogCallback, dialogShownCallback); + } + + public void ShowImage(Context context, Drawable drawable, string status = null, MaskType maskType = MaskType.Black, TimeSpan? timeout = null, Action clickCallback = null, Action cancelCallback = null, Action prepareDialogCallback = null, Action dialogShownCallback = null) + { + showImage(context, drawable, status, maskType, timeout, clickCallback, cancelCallback, prepareDialogCallback, dialogShownCallback); + } + + public void ShowToast(Context context, string status, MaskType maskType = MaskType.Black, TimeSpan? timeout = null, bool centered = true, Action clickCallback = null, Action cancelCallback = null, Action prepareDialogCallback = null, Action dialogShownCallback = null) + { + showStatus(context, false, status, maskType, timeout, clickCallback, centered, cancelCallback, prepareDialogCallback, dialogShownCallback); + } + + public void Dismiss(Context context = null) + { + DismissCurrent(context); + } Drawable GetDrawable(Context context, int drawableResourceId) { @@ -106,169 +106,169 @@ Drawable GetDrawable(Context context, int drawableResourceId) } void showStatus (Context context, bool spinner, string status = null, MaskType maskType = MaskType.Black, TimeSpan? timeout = null, Action clickCallback = null, bool centered = true, Action cancelCallback = null, Action prepareDialogCallback = null, Action dialogShownCallback = null) - { + { if (context == null) throw new ArgumentNullException(nameof(context)); - if (timeout == null) - timeout = TimeSpan.Zero; + if (timeout == null) + timeout = TimeSpan.Zero; - if (CurrentDialog != null && statusObj == null) - DismissCurrent (context); + if (CurrentDialog != null && statusObj == null) + DismissCurrent(context); - lock (dialogLock) - { - if (CurrentDialog == null) - { - SetupDialog (context, maskType, cancelCallback, (a, d, m) => { - View view = LayoutInflater.From (context).Inflate (Resource.Layout.loading, null); + lock (dialogLock) + { + if (CurrentDialog == null) + { + SetupDialog(context, maskType, cancelCallback, (a, d, m) => { + View view = LayoutInflater.From(context).Inflate(Resource.Layout.loading, null); - if (clickCallback != null) - view.Click += (sender, e) => clickCallback(); + if (clickCallback != null) + view.Click += (sender, e) => clickCallback(); - statusObj = new object(); + statusObj = new object(); - statusText = view.FindViewById(Resource.Id.textViewStatus); + statusText = view.FindViewById(Resource.Id.textViewStatus); - if (!spinner) - view.FindViewById(Resource.Id.loadingProgressBar).Visibility = ViewStates.Gone; + if (!spinner) + view.FindViewById(Resource.Id.loadingProgressBar).Visibility = ViewStates.Gone; - if (maskType != MaskType.Black) - view.SetBackgroundResource(Resource.Drawable.roundedbgdark); + if (maskType != MaskType.Black) + view.SetBackgroundResource(Resource.Drawable.roundedbgdark); - if (statusText != null) - { - statusText.Text = status ?? ""; - statusText.Visibility = string.IsNullOrEmpty(status) ? ViewStates.Gone : ViewStates.Visible; - } + if (statusText != null) + { + statusText.Text = status ?? ""; + statusText.Visibility = string.IsNullOrEmpty(status) ? ViewStates.Gone : ViewStates.Visible; + } - if (!centered) - { - d.Window.SetGravity (GravityFlags.Bottom); - var p = d.Window.Attributes; + if (!centered) + { + d.Window.SetGravity (GravityFlags.Bottom); + var p = d.Window.Attributes; - p.Y = DpToPx (context, 22); + p.Y = DpToPx (context, 22); - d.Window.Attributes = p; - } + d.Window.Attributes = p; + } - return view; - }, prepareDialogCallback, dialogShownCallback); + return view; + }, prepareDialogCallback, dialogShownCallback); RunTimeout(context, timeout); } - else - { - - Application.SynchronizationContext.Send(state => { - if (statusText != null) - statusText.Text = status ?? ""; - }, null); - } - } - } - - int DpToPx(Context context, int dp) - { - var displayMetrics = context.Resources.DisplayMetrics; + else + { + + Application.SynchronizationContext.Send(state => { + if (statusText != null) + statusText.Text = status ?? ""; + }, null); + } + } + } + + int DpToPx(Context context, int dp) + { + var displayMetrics = context.Resources.DisplayMetrics; return (int)TypedValue.ApplyDimension(ComplexUnitType.Dip, dp, displayMetrics); - } + } - void showProgress(Context context, int progress, string status = null, MaskType maskType = MaskType.Black, TimeSpan? timeout = null, Action clickCallback = null, Action cancelCallback = null, Action prepareDialogCallback = null, Action dialogShownCallback = null) - { - if (!timeout.HasValue || timeout == null) - timeout = TimeSpan.Zero; + void showProgress(Context context, int progress, string status = null, MaskType maskType = MaskType.Black, TimeSpan? timeout = null, Action clickCallback = null, Action cancelCallback = null, Action prepareDialogCallback = null, Action dialogShownCallback = null) + { + if (!timeout.HasValue || timeout == null) + timeout = TimeSpan.Zero; - if (CurrentDialog != null && progressWheel == null) - DismissCurrent (context); + if (CurrentDialog != null && progressWheel == null) + DismissCurrent(context); - lock (dialogLock) - { - if (CurrentDialog == null) - { - SetupDialog (context, maskType, cancelCallback, (a, d, m) => { - var inflater = LayoutInflater.FromContext(context); - var view = inflater.Inflate(Resource.Layout.loadingprogress, null); + lock (dialogLock) + { + if (CurrentDialog == null) + { + SetupDialog(context, maskType, cancelCallback, (a, d, m) => { + var inflater = LayoutInflater.FromContext(context); + var view = inflater.Inflate(Resource.Layout.loadingprogress, null); - if (clickCallback != null) - view.Click += (sender, e) => clickCallback(); + if (clickCallback != null) + view.Click += (sender, e) => clickCallback(); - progressWheel = view.FindViewById(Resource.Id.loadingProgressWheel); - statusText = view.FindViewById(Resource.Id.textViewStatus); + progressWheel = view.FindViewById(Resource.Id.loadingProgressWheel); + statusText = view.FindViewById(Resource.Id.textViewStatus); - if (maskType != MaskType.Black) - view.SetBackgroundResource(Resource.Drawable.roundedbgdark); + if (maskType != MaskType.Black) + view.SetBackgroundResource(Resource.Drawable.roundedbgdark); - progressWheel.SetProgress(0); + progressWheel.SetProgress(0); - if (statusText != null) - { - statusText.Text = status ?? ""; - statusText.Visibility = string.IsNullOrEmpty(status) ? ViewStates.Gone : ViewStates.Visible; - } + if (statusText != null) + { + statusText.Text = status ?? ""; + statusText.Visibility = string.IsNullOrEmpty(status) ? ViewStates.Gone : ViewStates.Visible; + } - return view; - }, prepareDialogCallback, dialogShownCallback); + return view; + }, prepareDialogCallback, dialogShownCallback); RunTimeout(context, timeout); } - else - { - Application.SynchronizationContext.Send(state => { - progressWheel?.SetProgress (progress); - statusText.Text = status ?? ""; - }, null); - } - } - } - - void showImage(Context context, Drawable image, string status = null, MaskType maskType = MaskType.Black, TimeSpan? timeout = null, Action clickCallback = null, Action cancelCallback = null, Action prepareDialogCallback = null, Action dialogShownCallback = null) - { - if (timeout == null) - timeout = TimeSpan.Zero; - - if (CurrentDialog != null && imageView == null) - DismissCurrent (context); - - lock (dialogLock) - { - if (CurrentDialog == null) - { - SetupDialog (context, maskType, cancelCallback, (a, d, m) => { - var inflater = LayoutInflater.FromContext(context); - var view = inflater.Inflate(Resource.Layout.loadingimage, null); - - if (clickCallback != null) - view.Click += (sender, e) => clickCallback(); - - imageView = view.FindViewById(Resource.Id.loadingImage); - statusText = view.FindViewById(Resource.Id.textViewStatus); - - if (maskType != MaskType.Black) - view.SetBackgroundResource(Resource.Drawable.roundedbgdark); + else + { + Application.SynchronizationContext.Send(state => { + progressWheel?.SetProgress(progress); + statusText.Text = status ?? ""; + }, null); + } + } + } + + void showImage(Context context, Drawable image, string status = null, MaskType maskType = MaskType.Black, TimeSpan? timeout = null, Action clickCallback = null, Action cancelCallback = null, Action prepareDialogCallback = null, Action dialogShownCallback = null) + { + if (timeout == null) + timeout = TimeSpan.Zero; + + if (CurrentDialog != null && imageView == null) + DismissCurrent(context); + + lock (dialogLock) + { + if (CurrentDialog == null) + { + SetupDialog(context, maskType, cancelCallback, (a, d, m) => { + var inflater = LayoutInflater.FromContext(context); + var view = inflater.Inflate(Resource.Layout.loadingimage, null); + + if (clickCallback != null) + view.Click += (sender, e) => clickCallback(); + + imageView = view.FindViewById(Resource.Id.loadingImage); + statusText = view.FindViewById(Resource.Id.textViewStatus); + + if (maskType != MaskType.Black) + view.SetBackgroundResource(Resource.Drawable.roundedbgdark); imageView?.SetImageDrawable(image); - if (statusText != null) - { - statusText.Text = status ?? ""; - statusText.Visibility = string.IsNullOrEmpty(status) ? ViewStates.Gone : ViewStates.Visible; - } + if (statusText != null) + { + statusText.Text = status ?? ""; + statusText.Visibility = string.IsNullOrEmpty(status) ? ViewStates.Gone : ViewStates.Visible; + } - return view; - }, prepareDialogCallback, dialogShownCallback); + return view; + }, prepareDialogCallback, dialogShownCallback); RunTimeout(context, timeout); - } - else - { - Application.SynchronizationContext.Send(state => { + } + else + { + Application.SynchronizationContext.Send(state => { imageView?.SetImageDrawable(image); - statusText.Text = status ?? ""; - }, null); - } - } - } + statusText.Text = status ?? ""; + }, null); + } + } + } void RunTimeout(Context context, TimeSpan? timeout) { @@ -288,71 +288,71 @@ void RunTimeout(Context context, TimeSpan? timeout) } void SetupDialog(Context context, MaskType maskType, Action cancelCallback, Func customSetup, Action prepareDialogCallback = null, Action dialogShownCallback = null) - { - Application.SynchronizationContext.Send(state => { + { + Application.SynchronizationContext.Send(state => { - var dialog = new Dialog(context); + var dialog = new Dialog(context); dialog.RequestWindowFeature((int)WindowFeatures.NoTitle); - if (maskType != MaskType.Black) + if (maskType != MaskType.Black) dialog.Window.ClearFlags(WindowManagerFlags.DimBehind); - if (maskType == MaskType.None) + if (maskType == MaskType.None) dialog.Window.SetFlags(WindowManagerFlags.NotTouchModal, WindowManagerFlags.NotTouchModal); dialog.Window.SetBackgroundDrawable(new ColorDrawable(Color.Transparent)); - var customView = customSetup(context, dialog, maskType); + var customView = customSetup(context, dialog, maskType); dialog.SetContentView (customView); - dialog.SetCancelable (cancelCallback != null); - if (cancelCallback != null) + dialog.SetCancelable(cancelCallback != null); + if (cancelCallback != null) dialog.CancelEvent += (sender, e) => cancelCallback(); prepareDialogCallback?.Invoke(dialog); CurrentDialog = dialog; - CurrentDialog.Show (); + CurrentDialog.Show(); dialogShownCallback?.Invoke(CurrentDialog); - }, null); - } + }, null); + } - void DismissCurrent(Context context = null) - { - lock (dialogLock) - { - if (CurrentDialog != null) - { - waitDismiss.Set (); + void DismissCurrent(Context context = null) + { + lock (dialogLock) + { + if (CurrentDialog != null) + { + waitDismiss.Set(); - Action actionDismiss = () => - { + Action actionDismiss = () => + { if (CurrentDialog != null) { CurrentDialog.Hide(); CurrentDialog.Dismiss(); } - statusText = null; - statusObj = null; - imageView = null; - progressWheel = null; - CurrentDialog = null; + statusText = null; + statusObj = null; + imageView = null; + progressWheel = null; + CurrentDialog = null; - waitDismiss.Reset (); - }; + waitDismiss.Reset(); + }; - // First try the SynchronizationContext - if (Application.SynchronizationContext != null) - { - Application.SynchronizationContext.Send (state => actionDismiss (), null); - return; - } + // First try the SynchronizationContext + if (Application.SynchronizationContext != null) + { + Application.SynchronizationContext.Send(state => actionDismiss(), null); + return; + } // Otherwise try OwnerActivity on dialog var ownerActivity = CurrentDialog.OwnerActivity; @@ -364,7 +364,7 @@ void DismissCurrent(Context context = null) // Otherwise try get it from the Window Context if (IsAlive(CurrentDialog?.Window?.Context)) - { + { if (CurrentDialog.Window.Context is Activity windowActivity) { windowActivity.RunOnUiThread(actionDismiss); @@ -380,8 +380,8 @@ void DismissCurrent(Context context = null) return; } } - } - } + } + } bool IsAlive(Java.Lang.Object @object) { @@ -405,11 +405,11 @@ bool IsAlive(Java.Lang.Object @object) } } - public enum MaskType - { - None = 1, - Clear = 2, - Black = 3 - } + public enum MaskType + { + None = 1, + Clear = 2, + Black = 3 + } } diff --git a/AndHUD/XHUD.cs b/AndHUD/XHUD.cs index 9588558..1d22d9c 100644 --- a/AndHUD/XHUD.cs +++ b/AndHUD/XHUD.cs @@ -5,37 +5,37 @@ namespace XHUD { - public enum MaskType - { + public enum MaskType + { // None = 1, - Clear = 2, - Black = 3, + Clear = 2, + Black = 3, // Gradient - } - - public static class HUD - { - public static Activity MyActivity; - - public static void Show(string message, int progress = -1, MaskType maskType = MaskType.Black) - { - AndHUD.Shared.Show(HUD.MyActivity, message, progress,(AndroidHUD.MaskType)maskType); - } - - public static void Dismiss() - { - AndHUD.Shared.Dismiss(HUD.MyActivity); - } - - public static void ShowToast(string message, bool showToastCentered = true, double timeoutMs = 1000) - { - AndHUD.Shared.ShowToast(HUD.MyActivity, message, (AndroidHUD.MaskType)MaskType.Black, TimeSpan.FromSeconds(timeoutMs/1000), showToastCentered); - } - - public static void ShowToast(string message, MaskType maskType, bool showToastCentered = true, double timeoutMs = 1000) - { - AndHUD.Shared.ShowToast(HUD.MyActivity, message, (AndroidHUD.MaskType)maskType, TimeSpan.FromSeconds(timeoutMs/1000), showToastCentered); - } - } + } + + public static class HUD + { + public static Activity MyActivity; + + public static void Show(string message, int progress = -1, MaskType maskType = MaskType.Black) + { + AndHUD.Shared.Show(HUD.MyActivity, message, progress,(AndroidHUD.MaskType)maskType); + } + + public static void Dismiss() + { + AndHUD.Shared.Dismiss(HUD.MyActivity); + } + + public static void ShowToast(string message, bool showToastCentered = true, double timeoutMs = 1000) + { + AndHUD.Shared.ShowToast(HUD.MyActivity, message, (AndroidHUD.MaskType)MaskType.Black, TimeSpan.FromSeconds(timeoutMs/1000), showToastCentered); + } + + public static void ShowToast(string message, MaskType maskType, bool showToastCentered = true, double timeoutMs = 1000) + { + AndHUD.Shared.ShowToast(HUD.MyActivity, message, (AndroidHUD.MaskType)maskType, TimeSpan.FromSeconds(timeoutMs/1000), showToastCentered); + } + } } From 63f603a66df52348b74ef3c2d1deed3642871bb1 Mon Sep 17 00:00:00 2001 From: Tomasz Cielecki Date: Tue, 15 Oct 2019 16:14:12 +0200 Subject: [PATCH 12/22] Move types --- AndHUD/AndHUD.cs | 7 ------- AndHUD/MaskType.cs | 9 +++++++++ AndHUD/XHUD.MaskType.cs | 8 ++++++++ AndHUD/XHUD.cs | 7 ------- 4 files changed, 17 insertions(+), 14 deletions(-) create mode 100644 AndHUD/MaskType.cs create mode 100644 AndHUD/XHUD.MaskType.cs diff --git a/AndHUD/AndHUD.cs b/AndHUD/AndHUD.cs index acca6bf..5ffcda7 100644 --- a/AndHUD/AndHUD.cs +++ b/AndHUD/AndHUD.cs @@ -404,12 +404,5 @@ bool IsAlive(Java.Lang.Object @object) return true; } } - - public enum MaskType - { - None = 1, - Clear = 2, - Black = 3 - } } diff --git a/AndHUD/MaskType.cs b/AndHUD/MaskType.cs new file mode 100644 index 0000000..bcb4f2e --- /dev/null +++ b/AndHUD/MaskType.cs @@ -0,0 +1,9 @@ +namespace AndroidHUD +{ + public enum MaskType + { + None = 1, + Clear = 2, + Black = 3 + } +} diff --git a/AndHUD/XHUD.MaskType.cs b/AndHUD/XHUD.MaskType.cs new file mode 100644 index 0000000..9276ea1 --- /dev/null +++ b/AndHUD/XHUD.MaskType.cs @@ -0,0 +1,8 @@ +namespace XHUD +{ + public enum MaskType + { + Clear = 2, + Black = 3, + } +} diff --git a/AndHUD/XHUD.cs b/AndHUD/XHUD.cs index 1d22d9c..2859b12 100644 --- a/AndHUD/XHUD.cs +++ b/AndHUD/XHUD.cs @@ -5,13 +5,6 @@ namespace XHUD { - public enum MaskType - { -// None = 1, - Clear = 2, - Black = 3, -// Gradient - } public static class HUD { From f78605a7e04bef0c13a1ba1cf555496febcb52f1 Mon Sep 17 00:00:00 2001 From: Tomasz Cielecki Date: Tue, 15 Oct 2019 16:14:23 +0200 Subject: [PATCH 13/22] Access modifiers --- AndHUD/AndHUD.cs | 42 ++- AndHUD/ProgressWheel.cs | 516 +++++++++++++----------------- AndHUD/XHUD.cs | 13 +- Samples/SampleApp/MainActivity.cs | 9 +- 4 files changed, 259 insertions(+), 321 deletions(-) diff --git a/AndHUD/AndHUD.cs b/AndHUD/AndHUD.cs index 5ffcda7..8cb1ae7 100644 --- a/AndHUD/AndHUD.cs +++ b/AndHUD/AndHUD.cs @@ -27,23 +27,22 @@ public static AndHUD Shared } } - public AndHUD() + protected AndHUD() { } - ManualResetEvent waitDismiss = new ManualResetEvent(false); + private ManualResetEvent waitDismiss = new ManualResetEvent(false); public Dialog CurrentDialog { get; private set; } - ProgressWheel progressWheel = null; - TextView statusText = null; - ImageView imageView = null; + private ProgressWheel progressWheel = null; + private TextView statusText = null; + private ImageView imageView = null; - object statusObj = null; + private object statusObj = null; - readonly object dialogLock = new object(); + private readonly object dialogLock = new object(); - - public void Show (Context context, string status = null, int progress = -1, MaskType maskType = MaskType.Black, TimeSpan? timeout = null, Action clickCallback = null, bool centered = true, Action cancelCallback = null, Action prepareDialogCallback = null, Action dialogShownCallback = null) + public void Show(Context context, string status = null, int progress = -1, MaskType maskType = MaskType.Black, TimeSpan? timeout = null, Action clickCallback = null, bool centered = true, Action cancelCallback = null, Action prepareDialogCallback = null, Action dialogShownCallback = null) { if (progress >= 0) showProgress(context, progress, status, maskType, timeout, clickCallback, cancelCallback, prepareDialogCallback, dialogShownCallback); @@ -91,7 +90,7 @@ public void Dismiss(Context context = null) DismissCurrent(context); } - Drawable GetDrawable(Context context, int drawableResourceId) + private Drawable GetDrawable(Context context, int drawableResourceId) { if (Build.VERSION.SdkInt >= BuildVersionCodes.Lollipop) { @@ -105,7 +104,7 @@ Drawable GetDrawable(Context context, int drawableResourceId) } } - void showStatus (Context context, bool spinner, string status = null, MaskType maskType = MaskType.Black, TimeSpan? timeout = null, Action clickCallback = null, bool centered = true, Action cancelCallback = null, Action prepareDialogCallback = null, Action dialogShownCallback = null) + private void showStatus(Context context, bool spinner, string status = null, MaskType maskType = MaskType.Black, TimeSpan? timeout = null, Action clickCallback = null, bool centered = true, Action cancelCallback = null, Action prepareDialogCallback = null, Action dialogShownCallback = null) { if (context == null) throw new ArgumentNullException(nameof(context)); @@ -144,10 +143,10 @@ void showStatus (Context context, bool spinner, string status = null, MaskType m if (!centered) { - d.Window.SetGravity (GravityFlags.Bottom); + d.Window.SetGravity(GravityFlags.Bottom); var p = d.Window.Attributes; - p.Y = DpToPx (context, 22); + p.Y = DpToPx(context, 22); d.Window.Attributes = p; } @@ -168,13 +167,13 @@ void showStatus (Context context, bool spinner, string status = null, MaskType m } } - int DpToPx(Context context, int dp) + private int DpToPx(Context context, int dp) { var displayMetrics = context.Resources.DisplayMetrics; return (int)TypedValue.ApplyDimension(ComplexUnitType.Dip, dp, displayMetrics); } - void showProgress(Context context, int progress, string status = null, MaskType maskType = MaskType.Black, TimeSpan? timeout = null, Action clickCallback = null, Action cancelCallback = null, Action prepareDialogCallback = null, Action dialogShownCallback = null) + private void showProgress(Context context, int progress, string status = null, MaskType maskType = MaskType.Black, TimeSpan? timeout = null, Action clickCallback = null, Action cancelCallback = null, Action prepareDialogCallback = null, Action dialogShownCallback = null) { if (!timeout.HasValue || timeout == null) timeout = TimeSpan.Zero; @@ -222,7 +221,7 @@ void showProgress(Context context, int progress, string status = null, MaskType } } - void showImage(Context context, Drawable image, string status = null, MaskType maskType = MaskType.Black, TimeSpan? timeout = null, Action clickCallback = null, Action cancelCallback = null, Action prepareDialogCallback = null, Action dialogShownCallback = null) + private void showImage(Context context, Drawable image, string status = null, MaskType maskType = MaskType.Black, TimeSpan? timeout = null, Action clickCallback = null, Action cancelCallback = null, Action prepareDialogCallback = null, Action dialogShownCallback = null) { if (timeout == null) timeout = TimeSpan.Zero; @@ -270,7 +269,7 @@ void showImage(Context context, Drawable image, string status = null, MaskType m } } - void RunTimeout(Context context, TimeSpan? timeout) + private void RunTimeout(Context context, TimeSpan? timeout) { if (timeout > TimeSpan.Zero) { @@ -287,7 +286,7 @@ void RunTimeout(Context context, TimeSpan? timeout) } } - void SetupDialog(Context context, MaskType maskType, Action cancelCallback, Func customSetup, Action prepareDialogCallback = null, Action dialogShownCallback = null) + private void SetupDialog(Context context, MaskType maskType, Action cancelCallback, Func customSetup, Action prepareDialogCallback = null, Action dialogShownCallback = null) { Application.SynchronizationContext.Send(state => { @@ -305,7 +304,7 @@ void SetupDialog(Context context, MaskType maskType, Action cancelCallback, Func var customView = customSetup(context, dialog, maskType); - dialog.SetContentView (customView); + dialog.SetContentView(customView); dialog.SetCancelable(cancelCallback != null); if (cancelCallback != null) @@ -322,7 +321,7 @@ void SetupDialog(Context context, MaskType maskType, Action cancelCallback, Func }, null); } - void DismissCurrent(Context context = null) + private void DismissCurrent(Context context = null) { lock (dialogLock) { @@ -383,7 +382,7 @@ void DismissCurrent(Context context = null) } } - bool IsAlive(Java.Lang.Object @object) + private bool IsAlive(Java.Lang.Object @object) { if (@object == null) return false; @@ -405,4 +404,3 @@ bool IsAlive(Java.Lang.Object @object) } } } - diff --git a/AndHUD/ProgressWheel.cs b/AndHUD/ProgressWheel.cs index a2e98c8..31741c3 100644 --- a/AndHUD/ProgressWheel.cs +++ b/AndHUD/ProgressWheel.cs @@ -8,291 +8,233 @@ namespace AndroidHUD { [Register("androidhud.ProgressWheel")] - public class ProgressWheel : View - { - public ProgressWheel(Context context) - : this(context, null, 0) - { - } - - public ProgressWheel(Context context, IAttributeSet attrs) - : this(context, attrs, 0) - { - } - - public ProgressWheel (Context context, IAttributeSet attrs, int defStyle) : base(context, attrs, defStyle) - { - CircleRadius = 80; - BarLength = 60; - BarWidth = 20; - RimWidth = 20; - TextSize = 20; - - //Padding (with defaults) - WheelPaddingTop = 5; - WheelPaddingBottom = 5; - WheelPaddingLeft = 5; - WheelPaddingRight = 5; - - //Colors (with defaults) - BarColor = Color.White; - CircleColor = Color.Transparent; - RimColor = Color.Gray; - TextColor = Color.White; - - //Animation - //The amount of pixels to move the bar by on each draw - SpinSpeed = 2; - //The number of milliseconds to wait inbetween each draw - DelayMillis = 0; - - spinHandler = new SpinHandler(msg => { - Invalidate (); - - if (isSpinning) - { - progress += SpinSpeed; - if (progress > 360) - progress = 0; - - spinHandler.SendEmptyMessageDelayed (0, DelayMillis); - } - }); - - - //ParseAttributes(context.ObtainStyledAttributes(attrs, null)); //TODO: swap null for R.styleable.ProgressWheel - } - -// public string Text -// { -// get { return text; } -// set { text = value; splitText = text.Split('\n'); } -// } - - //public string[] SplitText { get { return splitText; } } - - - public int CircleRadius { get;set; } - public int BarLength { get;set; } - public int BarWidth { get;set; } - public int TextSize { get;set; } - public int WheelPaddingTop { get;set; } - public int WheelPaddingBottom { get; set; } - public int WheelPaddingLeft { get;set; } - public int WheelPaddingRight { get;set; } - public Color BarColor { get;set; } - public Color CircleColor { get;set; } - public Color RimColor { get;set; } - public Shader RimShader { get { return rimPaint.Shader; } set { rimPaint.SetShader(value); } } - public Color TextColor { get;set; } - public int SpinSpeed { get;set; } - public int RimWidth { get;set; } - public int DelayMillis { get;set; } - - public bool IsSpinning { get { return isSpinning; } } - - //Sizes (with defaults) - int fullRadius = 100; - - //Paints - Paint barPaint = new Paint(); - Paint circlePaint = new Paint(); - Paint rimPaint = new Paint(); - Paint textPaint = new Paint(); - - //Rectangles - //RectF rectBounds = new RectF(); - RectF circleBounds = new RectF(); - - int progress = 0; - bool isSpinning = false; - SpinHandler spinHandler; - - Android.OS.BuildVersionCodes version = Android.OS.Build.VERSION.SdkInt; - - //Other - //string text = ""; - //string[] splitText = new string[]{}; - - protected override void OnAttachedToWindow () - { - base.OnAttachedToWindow (); - - SetupBounds (); - SetupPaints (); - - Invalidate (); - } - - void SetupPaints() - { - barPaint.Color = BarColor; - barPaint.AntiAlias = true; - barPaint.SetStyle (Paint.Style.Stroke); - barPaint.StrokeWidth = BarWidth; - - rimPaint.Color = RimColor; - rimPaint.AntiAlias = true; - rimPaint.SetStyle (Paint.Style.Stroke); - rimPaint.StrokeWidth = RimWidth; - - circlePaint.Color = CircleColor; - circlePaint.AntiAlias = true; - circlePaint.SetStyle(Paint.Style.Fill); - - textPaint.Color = TextColor; - textPaint.SetStyle(Paint.Style.Fill); - textPaint.AntiAlias = true; - textPaint.TextSize = TextSize; - } - - void SetupBounds() - { - circleBounds = new RectF(WheelPaddingLeft + BarWidth, - WheelPaddingTop + BarWidth, - this.LayoutParameters.Width - WheelPaddingRight - BarWidth, - this.LayoutParameters.Height - WheelPaddingBottom - BarWidth); - - fullRadius = (this.LayoutParameters.Width - WheelPaddingRight - BarWidth)/2; - CircleRadius = (fullRadius - BarWidth) + 1; - } - -// void ParseAttributes(Android.Content.Res.TypedArray a) -// { -// BarWidth = (int) a.GetDimension(R.styleable.ProgressWheel_barWidth, barWidth); -// RimWidth = (int) a.GetDimension(R.styleable.ProgressWheel_rimWidth, rimWidth); -// SpinSpeed = (int) a.GetDimension(R.styleable.ProgressWheel_spinSpeed, spinSpeed); -// DelayMillis = (int) a.GetInteger(R.styleable.ProgressWheel_delayMillis, delayMillis); -// -// if(DelayMillis < 0) -// DelayMillis = 0; -// -// BarColor = a.GetColor(R.styleable.ProgressWheel_barColor, barColor); -// BarLength = (int) a.GetDimension(R.styleable.ProgressWheel_barLength, barLength); -// TextSize = (int) a.GetDimension(R.styleable.ProgressWheel_textSize, textSize); -// TextColor = (int) a.GetColor(R.styleable.ProgressWheel_textColor, textColor); -// -// Text = a.GetString(R.styleable.ProgressWheel_text); -// -// RimColor = (int) a.GetColor(R.styleable.ProgressWheel_rimColor, rimColor); -// CircleColor = (int) a.GetColor(R.styleable.ProgressWheel_circleColor, circleColor); -// } - - - - //---------------------------------- - //Animation stuff - //---------------------------------- - protected override void OnDraw (Canvas canvas) - { - base.OnDraw (canvas); - - //Draw the rim - canvas.DrawArc(circleBounds, 360, 360, false, rimPaint); - - //Draw the bar - if(isSpinning) - canvas.DrawArc(circleBounds, progress - 90, BarLength, false, barPaint); - else - canvas.DrawArc(circleBounds, -90, progress, false, barPaint); - - //Draw the inner circle - canvas.DrawCircle((circleBounds.Width() / 2) + RimWidth + WheelPaddingLeft, - (circleBounds.Height() / 2) + RimWidth + WheelPaddingTop, - CircleRadius, - circlePaint); - - //Draw the text (attempts to center it horizontally and vertically) -// int offsetNum = 2; -// -// foreach (var s in splitText) -// { -// float offset = textPaint.MeasureText(s) / 2; -// -// canvas.DrawText(s, this.Width / 2 - offset, -// this.Height / 2 + (TextSize * (offsetNum)) -// - ((splitText.Length - 1) * (TextSize / 2)), textPaint); -// offsetNum++; -// } - } - - public void ResetCount() - { - progress = 0; - //Text = "0%"; - Invalidate(); - } - - public void StopSpinning() - { - isSpinning = false; - progress = 0; - spinHandler.RemoveMessages(0); - } - - - public void Spin() - { - isSpinning = true; - spinHandler.SendEmptyMessage(0); - } - - public void IncrementProgress() - { - - - isSpinning = false; - progress++; - //Text = Math.Round(((float)progress/(float)360)*(float)100) + "%"; - spinHandler.SendEmptyMessage(0); - } - - public void SetProgress(int i) { - isSpinning = false; - var newProgress = (int)((float)i / (float)100 * (float)360); - - if (version >= Android.OS.BuildVersionCodes.Honeycomb) - { - Android.Animation.ValueAnimator va = - (Android.Animation.ValueAnimator)Android.Animation.ValueAnimator.OfInt (progress, newProgress).SetDuration (250); - - va.Update += (sender, e) => { - var interimValue = (int)e.Animation.AnimatedValue; - - progress = interimValue; - - //Text = Math.Round(((float)interimValue/(float)360)*(float)100) + "%"; - - Invalidate (); - }; - - va.Start (); - } else { - progress = newProgress; - Invalidate (); - } - - spinHandler.SendEmptyMessage(0); - } - - - - class SpinHandler : Android.OS.Handler - { - public SpinHandler(Action msgAction) : base() - { - MessageAction = msgAction; - } - - public Action MessageAction { get; private set; } - - public override void HandleMessage (Android.OS.Message msg) - { - MessageAction (msg); - } - } - - - } + public class ProgressWheel : View + { + public ProgressWheel(Context context) + : this(context, null, 0) + { + } + + public ProgressWheel(Context context, IAttributeSet attrs) + : this(context, attrs, 0) + { + } + + public ProgressWheel(Context context, IAttributeSet attrs, int defStyle) : base(context, attrs, defStyle) + { + CircleRadius = 80; + BarLength = 60; + BarWidth = 20; + RimWidth = 20; + TextSize = 20; + + // Padding (with defaults) + WheelPaddingTop = 5; + WheelPaddingBottom = 5; + WheelPaddingLeft = 5; + WheelPaddingRight = 5; + + // Colors (with defaults) + BarColor = Color.White; + CircleColor = Color.Transparent; + RimColor = Color.Gray; + TextColor = Color.White; + + // Animation + // The amount of pixels to move the bar by on each draw + SpinSpeed = 2; + // The number of milliseconds to wait inbetween each draw + DelayMillis = 0; + + spinHandler = new SpinHandler(msg => { + Invalidate(); + + if (isSpinning) + { + progress += SpinSpeed; + if (progress > 360) + { + progress = 0; + } + + spinHandler.SendEmptyMessageDelayed(0, DelayMillis); + } + }); + } + + public int CircleRadius { get; set; } + public int BarLength { get; set; } + public int BarWidth { get; set; } + public int TextSize { get; set; } + public int WheelPaddingTop { get; set; } + public int WheelPaddingBottom { get; set; } + public int WheelPaddingLeft { get; set; } + public int WheelPaddingRight { get; set; } + public Color BarColor { get; set; } + public Color CircleColor { get; set; } + public Color RimColor { get; set; } + public Shader RimShader { get { return rimPaint.Shader; } set { rimPaint.SetShader(value); } } + public Color TextColor { get; set; } + public int SpinSpeed { get; set; } + public int RimWidth { get; set; } + public int DelayMillis { get; set; } + + public bool IsSpinning { get { return isSpinning; } } + + // Sizes (with defaults) + private int fullRadius = 100; + + // Paints + private Paint barPaint = new Paint(); + private Paint circlePaint = new Paint(); + private Paint rimPaint = new Paint(); + private Paint textPaint = new Paint(); + + // Rectangles + private RectF circleBounds = new RectF(); + + private int progress = 0; + private bool isSpinning = false; + private SpinHandler spinHandler; + + private Android.OS.BuildVersionCodes version = Android.OS.Build.VERSION.SdkInt; + + protected override void OnAttachedToWindow() + { + base.OnAttachedToWindow(); + + SetupBounds(); + SetupPaints(); + + Invalidate(); + } + + void SetupPaints() + { + barPaint.Color = BarColor; + barPaint.AntiAlias = true; + barPaint.SetStyle(Paint.Style.Stroke); + barPaint.StrokeWidth = BarWidth; + + rimPaint.Color = RimColor; + rimPaint.AntiAlias = true; + rimPaint.SetStyle(Paint.Style.Stroke); + rimPaint.StrokeWidth = RimWidth; + + circlePaint.Color = CircleColor; + circlePaint.AntiAlias = true; + circlePaint.SetStyle(Paint.Style.Fill); + + textPaint.Color = TextColor; + textPaint.SetStyle(Paint.Style.Fill); + textPaint.AntiAlias = true; + textPaint.TextSize = TextSize; + } + + void SetupBounds() + { + circleBounds = + new RectF(WheelPaddingLeft + BarWidth, + WheelPaddingTop + BarWidth, + this.LayoutParameters.Width - WheelPaddingRight - BarWidth, + this.LayoutParameters.Height - WheelPaddingBottom - BarWidth); + + fullRadius = (this.LayoutParameters.Width - WheelPaddingRight - BarWidth)/2; + CircleRadius = (fullRadius - BarWidth) + 1; + } + + // ---------------------------------- + // Animation stuff + // ---------------------------------- + protected override void OnDraw(Canvas canvas) + { + base.OnDraw(canvas); + + // Draw the rim + canvas.DrawArc(circleBounds, 360, 360, false, rimPaint); + + // Draw the bar + if (isSpinning) + canvas.DrawArc(circleBounds, progress - 90, BarLength, false, barPaint); + else + canvas.DrawArc(circleBounds, -90, progress, false, barPaint); + + // Draw the inner circle + canvas.DrawCircle( + (circleBounds.Width() / 2) + RimWidth + WheelPaddingLeft, + (circleBounds.Height() / 2) + RimWidth + WheelPaddingTop, + CircleRadius, + circlePaint); + } + + public void ResetCount() + { + progress = 0; + // Text = "0%"; + Invalidate(); + } + + public void StopSpinning() + { + isSpinning = false; + progress = 0; + spinHandler.RemoveMessages(0); + } + + public void Spin() + { + isSpinning = true; + spinHandler.SendEmptyMessage(0); + } + + public void IncrementProgress() + { + isSpinning = false; + progress++; + spinHandler.SendEmptyMessage(0); + } + + public void SetProgress(int i) { + isSpinning = false; + var newProgress = (int)((float)i / (float)100 * (float)360); + + if (version >= Android.OS.BuildVersionCodes.Honeycomb) + { + Android.Animation.ValueAnimator va = + (Android.Animation.ValueAnimator)Android.Animation.ValueAnimator.OfInt(progress, newProgress).SetDuration(250); + + va.Update += (sender, e) => { + var interimValue = (int)e.Animation.AnimatedValue; + + progress = interimValue; + + Invalidate(); + }; + + va.Start(); + } + else + { + progress = newProgress; + Invalidate(); + } + + spinHandler.SendEmptyMessage(0); + } + + private class SpinHandler : Android.OS.Handler + { + public SpinHandler(Action msgAction) : base() + { + MessageAction = msgAction; + } + + public Action MessageAction { get; private set; } + + public override void HandleMessage(Android.OS.Message msg) + { + MessageAction(msg); + } + } + } } - diff --git a/AndHUD/XHUD.cs b/AndHUD/XHUD.cs index 2859b12..dce2408 100644 --- a/AndHUD/XHUD.cs +++ b/AndHUD/XHUD.cs @@ -1,34 +1,31 @@ using System; using Android.App; - using AndroidHUD; namespace XHUD { - public static class HUD { - public static Activity MyActivity; + public static Activity MyActivity { get; set; } public static void Show(string message, int progress = -1, MaskType maskType = MaskType.Black) { - AndHUD.Shared.Show(HUD.MyActivity, message, progress,(AndroidHUD.MaskType)maskType); + AndHUD.Shared.Show(MyActivity, message, progress,(AndroidHUD.MaskType)maskType); } public static void Dismiss() { - AndHUD.Shared.Dismiss(HUD.MyActivity); + AndHUD.Shared.Dismiss(MyActivity); } public static void ShowToast(string message, bool showToastCentered = true, double timeoutMs = 1000) { - AndHUD.Shared.ShowToast(HUD.MyActivity, message, (AndroidHUD.MaskType)MaskType.Black, TimeSpan.FromSeconds(timeoutMs/1000), showToastCentered); + AndHUD.Shared.ShowToast(MyActivity, message, (AndroidHUD.MaskType)MaskType.Black, TimeSpan.FromSeconds(timeoutMs/1000), showToastCentered); } public static void ShowToast(string message, MaskType maskType, bool showToastCentered = true, double timeoutMs = 1000) { - AndHUD.Shared.ShowToast(HUD.MyActivity, message, (AndroidHUD.MaskType)maskType, TimeSpan.FromSeconds(timeoutMs/1000), showToastCentered); + AndHUD.Shared.ShowToast(MyActivity, message, (AndroidHUD.MaskType)maskType, TimeSpan.FromSeconds(timeoutMs/1000), showToastCentered); } } } - diff --git a/Samples/SampleApp/MainActivity.cs b/Samples/SampleApp/MainActivity.cs index 9a5d8e5..09903e3 100644 --- a/Samples/SampleApp/MainActivity.cs +++ b/Samples/SampleApp/MainActivity.cs @@ -13,7 +13,7 @@ namespace SampleApp [Activity(Label = "@string/app_name", Theme = "@style/AppTheme.NoActionBar", MainLauncher = true)] public class MainActivity : AppCompatActivity { - string[] _demos = new string[] { + private string[] _demos = new string[] { "Status Indicator Only", "Status Indicator and Text", "Non-Modal Indicator and Text", @@ -52,7 +52,9 @@ protected override void OnCreate(Bundle savedInstanceState) protected override void OnDestroy() { if (_listView != null) + { _listView.ItemClick -= OnItemClick; + } base.OnDestroy(); } @@ -114,7 +116,7 @@ private void OnItemClick(object sender, AdapterView.ItemClickEventArgs e) } } - void ShowProgressDemo(Action action) + private void ShowProgressDemo(Action action) { Task.Run(() => { int progress = 0; @@ -131,7 +133,7 @@ void ShowProgressDemo(Action action) }); } - void ShowDemo(Action action) + private void ShowDemo(Action action) { Task.Run(() => { @@ -144,4 +146,3 @@ void ShowDemo(Action action) } } } - From 0a3b0eb64f4291a9a69f1acf0e5560edc5be9b35 Mon Sep 17 00:00:00 2001 From: Tomasz Cielecki Date: Tue, 15 Oct 2019 16:14:53 +0200 Subject: [PATCH 14/22] Always run code analysis + C#8 --- AndHUD/AndHUD.csproj | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/AndHUD/AndHUD.csproj b/AndHUD/AndHUD.csproj index d0cb5c3..ce613c5 100644 --- a/AndHUD/AndHUD.csproj +++ b/AndHUD/AndHUD.csproj @@ -5,6 +5,9 @@ AndroidHUD AndHUD AndHUD is a Progress / HUD library for Android which allows you to easily add amazing HUDs to your app! + + true + latest @@ -13,5 +16,5 @@ - + \ No newline at end of file From dd095a9e0598dbe7943235f7657feb366408de58 Mon Sep 17 00:00:00 2001 From: Tomasz Cielecki Date: Tue, 15 Oct 2019 16:15:06 +0200 Subject: [PATCH 15/22] Remove old settings --- Samples/SampleApp/SampleApp.csproj | 9 --------- 1 file changed, 9 deletions(-) diff --git a/Samples/SampleApp/SampleApp.csproj b/Samples/SampleApp/SampleApp.csproj index 518c0e3..90f1ac3 100644 --- a/Samples/SampleApp/SampleApp.csproj +++ b/Samples/SampleApp/SampleApp.csproj @@ -17,7 +17,6 @@ Resources\Resource.designer.cs Resource Off - false v9.0 Properties\AndroidManifest.xml Resources @@ -35,10 +34,6 @@ True None False - false - false - false - false true d8 true @@ -55,10 +50,6 @@ False SdkOnly True - false - false - false - false true d8 true From 29a2e6075352425094bedc746d9a926ad907d2c7 Mon Sep 17 00:00:00 2001 From: Tomasz Cielecki Date: Tue, 15 Oct 2019 20:47:40 +0200 Subject: [PATCH 16/22] Bunch of cleanup --- AndHUD/AndHUD.cs | 529 ++++++++++++++++---------- AndHUD/Extensions/ObjectExtensions.cs | 52 +++ AndHUD/ProgressWheel.cs | 287 ++++++++------ AndHUD/XHUD.cs | 8 +- Samples/SampleApp/MainActivity.cs | 20 +- 5 files changed, 578 insertions(+), 318 deletions(-) create mode 100644 AndHUD/Extensions/ObjectExtensions.cs diff --git a/AndHUD/AndHUD.cs b/AndHUD/AndHUD.cs index 8cb1ae7..06eb297 100644 --- a/AndHUD/AndHUD.cs +++ b/AndHUD/AndHUD.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Threading; using System.Threading.Tasks; using Android.App; @@ -9,262 +9,419 @@ using Android.Util; using Android.Views; using Android.Widget; +using AndroidHUD.Extensions; namespace AndroidHUD { - public class AndHUD + /// + /// Android HUD. + /// + public class AndHUD : IDisposable { - static AndHUD shared; + private static AndHUD _shared; + private readonly object _dialogLock = new object(); + private readonly ManualResetEvent _waitDismiss = new ManualResetEvent(false); + private ProgressWheel _progressWheel; + private TextView _statusText; + private ImageView _imageView; + + private object _statusObj; + + private AndHUD() + { + } + + /// + /// Gets the static instance of AndHUD. + /// public static AndHUD Shared { get { - if (shared == null) - shared = new AndHUD(); + if (_shared == null) + { + _shared = new AndHUD(); + } - return shared; + return _shared; } } - protected AndHUD() - { - } - - private ManualResetEvent waitDismiss = new ManualResetEvent(false); + /// + /// Gets the currently shown dialog. + /// public Dialog CurrentDialog { get; private set; } - private ProgressWheel progressWheel = null; - private TextView statusText = null; - private ImageView imageView = null; - - private object statusObj = null; - - private readonly object dialogLock = new object(); - + /// + /// Show a dialog with a progress indicator. + /// If is provided it will be shown determinate, otherwise indeterminate. + /// + /// Android needed to show the dialog. + /// Status text to show under progress or loading indicator. + /// Progress, if over 0, then you should call this method again to update the progress. + /// indicating, whether background should be masked. + /// Timeout to automatically dismiss the dialog. + /// Callback for when dialog is clicked. + /// Center dialog if true, otherwise align towards bottom. + /// Callback for when dialog is dismissed by clicking outside of it. + /// Callback for preparing the dialog. + /// Callback for when dialog is shown on the screen. public void Show(Context context, string status = null, int progress = -1, MaskType maskType = MaskType.Black, TimeSpan? timeout = null, Action clickCallback = null, bool centered = true, Action cancelCallback = null, Action prepareDialogCallback = null, Action dialogShownCallback = null) { if (progress >= 0) - showProgress(context, progress, status, maskType, timeout, clickCallback, cancelCallback, prepareDialogCallback, dialogShownCallback); + { + ShowProgress(context, progress, status, maskType, timeout, clickCallback, cancelCallback, prepareDialogCallback, dialogShownCallback); + } else - showStatus(context, true, status, maskType, timeout, clickCallback, centered, cancelCallback, prepareDialogCallback, dialogShownCallback); + { + ShowStatus(context, true, status, maskType, timeout, clickCallback, centered, cancelCallback, prepareDialogCallback, dialogShownCallback); + } } + /// + /// Show a dialog with an success image. + /// + /// Android needed to show the dialog. + /// Status text to show under the success image. + /// indicating, whether background should be masked. + /// Timeout to automatically dismiss the dialog. + /// Callback for when dialog is clicked. + /// Callback for when dialog is dismissed by clicking outside of it. + /// Callback for preparing the dialog. + /// Callback for when dialog is shown on the screen. public void ShowSuccess(Context context, string status = null, MaskType maskType = MaskType.Black, TimeSpan? timeout = null, Action clickCallback = null, Action cancelCallback = null, Action prepareDialogCallback = null, Action dialogShownCallback = null) { - showImage(context, GetDrawable(context, Resource.Drawable.ic_successstatus), status, maskType, timeout, clickCallback, cancelCallback, prepareDialogCallback, dialogShownCallback); + ShowImage(context, Resource.Drawable.ic_successstatus, status, maskType, timeout, clickCallback, cancelCallback, prepareDialogCallback, dialogShownCallback); } + /// + /// Show a dialog with an error image. + /// + /// Android needed to show the dialog. + /// Status text to show under the error image. + /// indicating, whether background should be masked. + /// Timeout to automatically dismiss the dialog. + /// Callback for when dialog is clicked. + /// Callback for when dialog is dismissed by clicking outside of it. + /// Callback for preparing the dialog. + /// Callback for when dialog is shown on the screen. public void ShowError(Context context, string status = null, MaskType maskType = MaskType.Black, TimeSpan? timeout = null, Action clickCallback = null, Action cancelCallback = null, Action prepareDialogCallback = null, Action dialogShownCallback = null) { - showImage(context, GetDrawable(context, Resource.Drawable.ic_errorstatus), status, maskType, timeout, clickCallback, cancelCallback, prepareDialogCallback, dialogShownCallback); + ShowImage(context, Resource.Drawable.ic_errorstatus, status, maskType, timeout, clickCallback, cancelCallback, prepareDialogCallback, dialogShownCallback); } - public void ShowSuccessWithStatus(Context context, string status, MaskType maskType = MaskType.Black, TimeSpan? timeout = null, Action clickCallback = null, Action cancelCallback = null, Action prepareDialogCallback = null, Action dialogShownCallback = null) + /// + /// Show a dialog with an image. + /// + /// Android needed to show the dialog. + /// Android drawable resource id. + /// Status text to show under the image. + /// indicating, whether background should be masked. + /// Timeout to automatically dismiss the dialog. + /// Callback for when dialog is clicked. + /// Callback for when dialog is dismissed by clicking outside of it. + /// Callback for preparing the dialog. + /// Callback for when dialog is shown on the screen. + public void ShowImage(Context context, int drawableResourceId, string status = null, MaskType maskType = MaskType.Black, TimeSpan? timeout = null, Action clickCallback = null, Action cancelCallback = null, Action prepareDialogCallback = null, Action dialogShownCallback = null) { - showImage(context, GetDrawable(context, Resource.Drawable.ic_successstatus), status, maskType, timeout, clickCallback, cancelCallback, prepareDialogCallback, dialogShownCallback); + ShowImage(context, GetDrawable(context, drawableResourceId), status, maskType, timeout, clickCallback, cancelCallback, prepareDialogCallback, dialogShownCallback); } - public void ShowErrorWithStatus(Context context, string status, MaskType maskType = MaskType.Black, TimeSpan? timeout = null, Action clickCallback = null, Action cancelCallback = null, Action prepareDialogCallback = null, Action dialogShownCallback = null) + /// + /// Show a dialog with an image. + /// + /// Android needed to show the dialog. + /// Android drawable resource. + /// Status text to show under the image. + /// indicating, whether background should be masked. + /// Timeout to automatically dismiss the dialog. + /// Callback for when dialog is clicked. + /// Callback for when dialog is dismissed by clicking outside of it. + /// Callback for preparing the dialog. + /// Callback for when dialog is shown on the screen. + public void ShowImage(Context context, Drawable drawable, string status = null, MaskType maskType = MaskType.Black, TimeSpan? timeout = null, Action clickCallback = null, Action cancelCallback = null, Action prepareDialogCallback = null, Action dialogShownCallback = null) { - showImage(context, GetDrawable(context, Resource.Drawable.ic_errorstatus), status, maskType, timeout, clickCallback, cancelCallback, prepareDialogCallback, dialogShownCallback); + ShowWithImage(context, drawable, status, maskType, timeout, clickCallback, cancelCallback, prepareDialogCallback, dialogShownCallback); } - public void ShowImage(Context context, int drawableResourceId, string status = null, MaskType maskType = MaskType.Black, TimeSpan? timeout = null, Action clickCallback = null, Action cancelCallback = null, Action prepareDialogCallback = null, Action dialogShownCallback = null) + /// + /// Show a toast dialog. + /// + /// Android needed to show the dialog. + /// Status text to show. + /// indicating, whether background should be masked. + /// Timeout to automatically dismiss the dialog. + /// Center dialog if true, otherwise align towards bottom. + /// Callback for when dialog is clicked. + /// Callback for when dialog is dismissed by clicking outside of it. + /// Callback for preparing the dialog. + /// Callback for when dialog is shown on the screen. + public void ShowToast(Context context, string status, MaskType maskType = MaskType.Black, TimeSpan? timeout = null, bool centered = true, Action clickCallback = null, Action cancelCallback = null, Action prepareDialogCallback = null, Action dialogShownCallback = null) { - showImage(context, GetDrawable(context, drawableResourceId), status, maskType, timeout, clickCallback, cancelCallback, prepareDialogCallback, dialogShownCallback); + ShowStatus(context, false, status, maskType, timeout, clickCallback, centered, cancelCallback, prepareDialogCallback, dialogShownCallback); } - public void ShowImage(Context context, Drawable drawable, string status = null, MaskType maskType = MaskType.Black, TimeSpan? timeout = null, Action clickCallback = null, Action cancelCallback = null, Action prepareDialogCallback = null, Action dialogShownCallback = null) + /// + /// Dismiss currently shown dialog. + /// + /// Android needed to dismiss the dialog. + public void Dismiss(Context context = null) { - showImage(context, drawable, status, maskType, timeout, clickCallback, cancelCallback, prepareDialogCallback, dialogShownCallback); + DismissCurrent(context); } - public void ShowToast(Context context, string status, MaskType maskType = MaskType.Black, TimeSpan? timeout = null, bool centered = true, Action clickCallback = null, Action cancelCallback = null, Action prepareDialogCallback = null, Action dialogShownCallback = null) + /// + public void Dispose() { - showStatus(context, false, status, maskType, timeout, clickCallback, centered, cancelCallback, prepareDialogCallback, dialogShownCallback); + Dispose(true); + GC.SuppressFinalize(this); } - public void Dismiss(Context context = null) + /// + /// Dispose managed resources. + /// + /// Is disposing from call. + protected virtual void Dispose(bool disposing) { - DismissCurrent(context); + if (disposing) + { + _progressWheel.Dispose(); + _statusText.Dispose(); + _imageView.Dispose(); + _waitDismiss.Dispose(); + } } - private Drawable GetDrawable(Context context, int drawableResourceId) + private static Drawable GetDrawable(Context context, int drawableResourceId) { if (Build.VERSION.SdkInt >= BuildVersionCodes.Lollipop) { return context.Resources.GetDrawable(drawableResourceId, context.Theme); } - else - { + #pragma warning disable CS0618 // Type or member is obsolete - return context.Resources.GetDrawable(drawableResourceId); + return context.Resources.GetDrawable(drawableResourceId); #pragma warning restore CS0618 // Type or member is obsolete - } } - private void showStatus(Context context, bool spinner, string status = null, MaskType maskType = MaskType.Black, TimeSpan? timeout = null, Action clickCallback = null, bool centered = true, Action cancelCallback = null, Action prepareDialogCallback = null, Action dialogShownCallback = null) + private static int DpToPx(Context context, int dp) + { + var displayMetrics = context.Resources.DisplayMetrics; + return (int)TypedValue.ApplyDimension(ComplexUnitType.Dip, dp, displayMetrics); + } + + private void ShowStatus(Context context, bool spinner, string status = null, MaskType maskType = MaskType.Black, TimeSpan? timeout = null, Action clickCallback = null, bool centered = true, Action cancelCallback = null, Action prepareDialogCallback = null, Action dialogShownCallback = null) { if (context == null) + { throw new ArgumentNullException(nameof(context)); + } if (timeout == null) + { timeout = TimeSpan.Zero; + } - if (CurrentDialog != null && statusObj == null) + if (CurrentDialog != null && _statusObj == null) + { DismissCurrent(context); + } - lock (dialogLock) + lock (_dialogLock) { if (CurrentDialog == null) { - SetupDialog(context, maskType, cancelCallback, (a, d, m) => { - View view = LayoutInflater.From(context).Inflate(Resource.Layout.loading, null); + SetupDialog( + context, + maskType, + cancelCallback, + (_, d, __) => + { + View view = LayoutInflater.From(context).Inflate(Resource.Layout.loading, null); - if (clickCallback != null) - view.Click += (sender, e) => clickCallback(); + if (clickCallback != null) + { + view.Click += (sender, e) => clickCallback(); + } - statusObj = new object(); + _statusObj = new object(); - statusText = view.FindViewById(Resource.Id.textViewStatus); + _statusText = view.FindViewById(Resource.Id.textViewStatus); - if (!spinner) - view.FindViewById(Resource.Id.loadingProgressBar).Visibility = ViewStates.Gone; + if (!spinner) + { + view.FindViewById(Resource.Id.loadingProgressBar).Visibility = ViewStates.Gone; + } - if (maskType != MaskType.Black) - view.SetBackgroundResource(Resource.Drawable.roundedbgdark); + if (maskType != MaskType.Black) + { + view.SetBackgroundResource(Resource.Drawable.roundedbgdark); + } - if (statusText != null) - { - statusText.Text = status ?? ""; - statusText.Visibility = string.IsNullOrEmpty(status) ? ViewStates.Gone : ViewStates.Visible; - } + if (_statusText != null) + { + _statusText.Text = status ?? string.Empty; + _statusText.Visibility = string.IsNullOrEmpty(status) ? ViewStates.Gone : ViewStates.Visible; + } - if (!centered) - { - d.Window.SetGravity(GravityFlags.Bottom); - var p = d.Window.Attributes; + if (!centered) + { + d.Window.SetGravity(GravityFlags.Bottom); + var p = d.Window.Attributes; - p.Y = DpToPx(context, 22); + p.Y = DpToPx(context, 22); - d.Window.Attributes = p; - } + d.Window.Attributes = p; + } - return view; - }, prepareDialogCallback, dialogShownCallback); + return view; + }, + prepareDialogCallback, + dialogShownCallback); RunTimeout(context, timeout); } else { - - Application.SynchronizationContext.Send(state => { - if (statusText != null) - statusText.Text = status ?? ""; - }, null); + Application.SynchronizationContext.Send( + _ => + { + if (_statusText != null) + { + _statusText.Text = status ?? string.Empty; + } + }, null); } } } - private int DpToPx(Context context, int dp) - { - var displayMetrics = context.Resources.DisplayMetrics; - return (int)TypedValue.ApplyDimension(ComplexUnitType.Dip, dp, displayMetrics); - } - - private void showProgress(Context context, int progress, string status = null, MaskType maskType = MaskType.Black, TimeSpan? timeout = null, Action clickCallback = null, Action cancelCallback = null, Action prepareDialogCallback = null, Action dialogShownCallback = null) + private void ShowProgress(Context context, int progress, string status = null, MaskType maskType = MaskType.Black, TimeSpan? timeout = null, Action clickCallback = null, Action cancelCallback = null, Action prepareDialogCallback = null, Action dialogShownCallback = null) { if (!timeout.HasValue || timeout == null) + { timeout = TimeSpan.Zero; + } - if (CurrentDialog != null && progressWheel == null) + if (CurrentDialog != null && _progressWheel == null) + { DismissCurrent(context); + } - lock (dialogLock) + lock (_dialogLock) { if (CurrentDialog == null) { - SetupDialog(context, maskType, cancelCallback, (a, d, m) => { - var inflater = LayoutInflater.FromContext(context); - var view = inflater.Inflate(Resource.Layout.loadingprogress, null); + SetupDialog( + context, + maskType, + cancelCallback, + (a, d, m) => + { + var inflater = LayoutInflater.FromContext(context); + var view = inflater.Inflate(Resource.Layout.loadingprogress, null); - if (clickCallback != null) - view.Click += (sender, e) => clickCallback(); + if (clickCallback != null) + { + view.Click += (sender, e) => clickCallback(); + } - progressWheel = view.FindViewById(Resource.Id.loadingProgressWheel); - statusText = view.FindViewById(Resource.Id.textViewStatus); + _progressWheel = view.FindViewById(Resource.Id.loadingProgressWheel); + _statusText = view.FindViewById(Resource.Id.textViewStatus); - if (maskType != MaskType.Black) - view.SetBackgroundResource(Resource.Drawable.roundedbgdark); + if (maskType != MaskType.Black) + { + view.SetBackgroundResource(Resource.Drawable.roundedbgdark); + } - progressWheel.SetProgress(0); + _progressWheel.SetProgress(0); - if (statusText != null) - { - statusText.Text = status ?? ""; - statusText.Visibility = string.IsNullOrEmpty(status) ? ViewStates.Gone : ViewStates.Visible; - } + if (_statusText != null) + { + _statusText.Text = status ?? string.Empty; + _statusText.Visibility = string.IsNullOrEmpty(status) ? ViewStates.Gone : ViewStates.Visible; + } - return view; - }, prepareDialogCallback, dialogShownCallback); + return view; + }, + prepareDialogCallback, + dialogShownCallback); RunTimeout(context, timeout); } else { - Application.SynchronizationContext.Send(state => { - progressWheel?.SetProgress(progress); - statusText.Text = status ?? ""; - }, null); + Application.SynchronizationContext.Send( + _ => + { + _progressWheel?.SetProgress(progress); + _statusText.Text = status ?? string.Empty; + }, null); } } } - private void showImage(Context context, Drawable image, string status = null, MaskType maskType = MaskType.Black, TimeSpan? timeout = null, Action clickCallback = null, Action cancelCallback = null, Action prepareDialogCallback = null, Action dialogShownCallback = null) + private void ShowWithImage(Context context, Drawable image, string status = null, MaskType maskType = MaskType.Black, TimeSpan? timeout = null, Action clickCallback = null, Action cancelCallback = null, Action prepareDialogCallback = null, Action dialogShownCallback = null) { if (timeout == null) + { timeout = TimeSpan.Zero; + } - if (CurrentDialog != null && imageView == null) + if (CurrentDialog != null && _imageView == null) + { DismissCurrent(context); + } - lock (dialogLock) + lock (_dialogLock) { if (CurrentDialog == null) { - SetupDialog(context, maskType, cancelCallback, (a, d, m) => { - var inflater = LayoutInflater.FromContext(context); - var view = inflater.Inflate(Resource.Layout.loadingimage, null); + SetupDialog( + context, + maskType, + cancelCallback, + (a, d, m) => + { + var inflater = LayoutInflater.FromContext(context); + var view = inflater.Inflate(Resource.Layout.loadingimage, null); - if (clickCallback != null) - view.Click += (sender, e) => clickCallback(); + if (clickCallback != null) + { + view.Click += (sender, e) => clickCallback(); + } - imageView = view.FindViewById(Resource.Id.loadingImage); - statusText = view.FindViewById(Resource.Id.textViewStatus); + _imageView = view.FindViewById(Resource.Id.loadingImage); + _statusText = view.FindViewById(Resource.Id.textViewStatus); - if (maskType != MaskType.Black) - view.SetBackgroundResource(Resource.Drawable.roundedbgdark); + if (maskType != MaskType.Black) + { + view.SetBackgroundResource(Resource.Drawable.roundedbgdark); + } - imageView?.SetImageDrawable(image); + _imageView?.SetImageDrawable(image); - if (statusText != null) - { - statusText.Text = status ?? ""; - statusText.Visibility = string.IsNullOrEmpty(status) ? ViewStates.Gone : ViewStates.Visible; - } + if (_statusText != null) + { + _statusText.Text = status ?? string.Empty; + _statusText.Visibility = string.IsNullOrEmpty(status) ? ViewStates.Gone : ViewStates.Visible; + } - return view; - }, prepareDialogCallback, dialogShownCallback); + return view; + }, + prepareDialogCallback, + dialogShownCallback); RunTimeout(context, timeout); } else { - Application.SynchronizationContext.Send(state => { - imageView?.SetImageDrawable(image); - statusText.Text = status ?? ""; - }, null); + Application.SynchronizationContext.Send( + state => + { + _imageView?.SetImageDrawable(image); + _statusText.Text = status ?? string.Empty; + }, null); } } } @@ -273,61 +430,75 @@ private void RunTimeout(Context context, TimeSpan? timeout) { if (timeout > TimeSpan.Zero) { - Task.Run(() => { - if (!waitDismiss.WaitOne(timeout.Value)) + _ = Task.Run(() => + { + if (!_waitDismiss.WaitOne(timeout.Value)) + { DismissCurrent(context); + } + }) + .ContinueWith( + ct => + { + var ex = ct.Exception; - }).ContinueWith(ct => { - var ex = ct.Exception; - - if (ex != null) - Android.Util.Log.Error("AndHUD", ex.ToString()); - }, TaskContinuationOptions.OnlyOnFaulted); + if (ex != null) + { + Android.Util.Log.Error("AndHUD", ex.ToString()); + } + }, + TaskContinuationOptions.OnlyOnFaulted); } } private void SetupDialog(Context context, MaskType maskType, Action cancelCallback, Func customSetup, Action prepareDialogCallback = null, Action dialogShownCallback = null) { - Application.SynchronizationContext.Send(state => { - - var dialog = new Dialog(context); - - dialog.RequestWindowFeature((int)WindowFeatures.NoTitle); + Application.SynchronizationContext.Send( + state => + { + var dialog = new Dialog(context); - if (maskType != MaskType.Black) - dialog.Window.ClearFlags(WindowManagerFlags.DimBehind); + dialog.RequestWindowFeature((int)WindowFeatures.NoTitle); - if (maskType == MaskType.None) - dialog.Window.SetFlags(WindowManagerFlags.NotTouchModal, WindowManagerFlags.NotTouchModal); + if (maskType != MaskType.Black) + { + dialog.Window.ClearFlags(WindowManagerFlags.DimBehind); + } - dialog.Window.SetBackgroundDrawable(new ColorDrawable(Color.Transparent)); + if (maskType == MaskType.None) + { + dialog.Window.SetFlags(WindowManagerFlags.NotTouchModal, WindowManagerFlags.NotTouchModal); + } - var customView = customSetup(context, dialog, maskType); + dialog.Window.SetBackgroundDrawable(new ColorDrawable(Color.Transparent)); - dialog.SetContentView(customView); + var customView = customSetup(context, dialog, maskType); - dialog.SetCancelable(cancelCallback != null); - if (cancelCallback != null) - dialog.CancelEvent += (sender, e) => cancelCallback(); + dialog.SetContentView(customView); - prepareDialogCallback?.Invoke(dialog); + dialog.SetCancelable(cancelCallback != null); + if (cancelCallback != null) + { + dialog.CancelEvent += (sender, e) => cancelCallback(); + } - CurrentDialog = dialog; + prepareDialogCallback?.Invoke(dialog); - CurrentDialog.Show(); + CurrentDialog = dialog; - dialogShownCallback?.Invoke(CurrentDialog); + CurrentDialog.Show(); - }, null); + dialogShownCallback?.Invoke(CurrentDialog); + }, null); } private void DismissCurrent(Context context = null) { - lock (dialogLock) + lock (_dialogLock) { if (CurrentDialog != null) { - waitDismiss.Set(); + _waitDismiss.Set(); Action actionDismiss = () => { @@ -337,13 +508,13 @@ private void DismissCurrent(Context context = null) CurrentDialog.Dismiss(); } - statusText = null; - statusObj = null; - imageView = null; - progressWheel = null; + _statusText = null; + _statusObj = null; + _imageView = null; + _progressWheel = null; CurrentDialog = null; - waitDismiss.Reset(); + _waitDismiss.Reset(); }; // First try the SynchronizationContext @@ -355,52 +526,28 @@ private void DismissCurrent(Context context = null) // Otherwise try OwnerActivity on dialog var ownerActivity = CurrentDialog.OwnerActivity; - if (IsAlive(ownerActivity)) + if (ownerActivity.IsAlive()) { ownerActivity.RunOnUiThread(actionDismiss); return; } // Otherwise try get it from the Window Context - if (IsAlive(CurrentDialog?.Window?.Context)) + if (CurrentDialog.Window.Context is Activity windowActivity && windowActivity.IsAlive()) { - if (CurrentDialog.Window.Context is Activity windowActivity) - { - windowActivity.RunOnUiThread(actionDismiss); - return; - } + windowActivity.RunOnUiThread(actionDismiss); + return; } // Finally if all else fails, let's see if someone passed in a context to dismiss and it // happens to also be an Activity - if (context != null && context is Activity activity) + if (context != null && context is Activity activity && activity.IsAlive()) { - activity?.RunOnUiThread(actionDismiss); + activity.RunOnUiThread(actionDismiss); return; } } } } - - private bool IsAlive(Java.Lang.Object @object) - { - if (@object == null) - return false; - - if (@object.Handle == IntPtr.Zero) - return false; - - if (@object is Activity activity) - { - if (activity.IsFinishing) - return false; - - if (Build.VERSION.SdkInt >= BuildVersionCodes.JellyBeanMr1 && - activity.IsDestroyed) - return false; - } - - return true; - } } } diff --git a/AndHUD/Extensions/ObjectExtensions.cs b/AndHUD/Extensions/ObjectExtensions.cs new file mode 100644 index 0000000..849af4b --- /dev/null +++ b/AndHUD/Extensions/ObjectExtensions.cs @@ -0,0 +1,52 @@ +using System; +using Android.App; +using Android.OS; + +namespace AndroidHUD.Extensions +{ + /// + /// Extensions for Java.Lang.Object. + /// + internal static class ObjectExtensions + { + /// + /// Checks whether a Java.Lang.Object is null, handle is Zero or if the type + /// is an Android Activity, then check whether it is Finishing or Destroyed. + /// + /// A to check for liveliness. + /// + /// Returns false if is . + /// Returns false if is . + /// Returns false if is an and is true. + /// Returns false if is an and is true. + /// + internal static bool IsAlive(this Java.Lang.Object thing) + { + if (thing == null) + { + return false; + } + + if (thing.Handle == IntPtr.Zero) + { + return false; + } + + if (thing is Activity activity) + { + if (activity.IsFinishing) + { + return false; + } + + if (Build.VERSION.SdkInt >= BuildVersionCodes.JellyBeanMr1 + && activity.IsDestroyed) + { + return false; + } + } + + return true; + } + } +} diff --git a/AndHUD/ProgressWheel.cs b/AndHUD/ProgressWheel.cs index 31741c3..63341aa 100644 --- a/AndHUD/ProgressWheel.cs +++ b/AndHUD/ProgressWheel.cs @@ -1,15 +1,36 @@ -using System; -using Android.Views; -using Android.Graphics; -using Android.Util; +using System; using Android.Content; +using Android.Graphics; using Android.Runtime; +using Android.Util; +using Android.Views; +using AndroidHUD.Extensions; namespace AndroidHUD { + /// + /// Progress Wheel View for showing circular progress. + /// [Register("androidhud.ProgressWheel")] public class ProgressWheel : View { + // Sizes (with defaults) + private int _fullRadius = 100; + + // Paints + private Paint _barPaint = new Paint(); + private Paint _circlePaint = new Paint(); + private Paint _rimPaint = new Paint(); + private Paint _textPaint = new Paint(); + + // Rectangles + private RectF _circleBounds = new RectF(); + + private int _progress = 0; + private SpinHandler _spinHandler; + + private Android.OS.BuildVersionCodes _version = Android.OS.Build.VERSION.SdkInt; + public ProgressWheel(Context context) : this(context, null, 0) { @@ -20,7 +41,8 @@ public ProgressWheel(Context context, IAttributeSet attrs) { } - public ProgressWheel(Context context, IAttributeSet attrs, int defStyle) : base(context, attrs, defStyle) + public ProgressWheel(Context context, IAttributeSet attrs, int defStyle) + : base(context, attrs, defStyle) { CircleRadius = 80; BarLength = 60; @@ -43,188 +65,221 @@ public ProgressWheel(Context context, IAttributeSet attrs, int defStyle) : base( // Animation // The amount of pixels to move the bar by on each draw SpinSpeed = 2; + // The number of milliseconds to wait inbetween each draw DelayMillis = 0; - spinHandler = new SpinHandler(msg => { + _spinHandler = new SpinHandler(msg => + { Invalidate(); - if (isSpinning) + if (IsSpinning) { - progress += SpinSpeed; - if (progress > 360) + _progress += SpinSpeed; + if (_progress > 360) { - progress = 0; + _progress = 0; } - spinHandler.SendEmptyMessageDelayed(0, DelayMillis); + _spinHandler.SendEmptyMessageDelayed(0, DelayMillis); } }); } public int CircleRadius { get; set; } + public int BarLength { get; set; } + public int BarWidth { get; set; } + public int TextSize { get; set; } + public int WheelPaddingTop { get; set; } + public int WheelPaddingBottom { get; set; } + public int WheelPaddingLeft { get; set; } + public int WheelPaddingRight { get; set; } + public Color BarColor { get; set; } + public Color CircleColor { get; set; } + public Color RimColor { get; set; } - public Shader RimShader { get { return rimPaint.Shader; } set { rimPaint.SetShader(value); } } + + public Shader RimShader + { + get => _rimPaint.Shader; + set => _rimPaint.SetShader(value); + } + public Color TextColor { get; set; } + public int SpinSpeed { get; set; } + public int RimWidth { get; set; } + public int DelayMillis { get; set; } - public bool IsSpinning { get { return isSpinning; } } + public bool IsSpinning { get; private set; } - // Sizes (with defaults) - private int fullRadius = 100; + /// + /// Reset progress to 0. + /// + public void ResetCount() + { + _progress = 0; - // Paints - private Paint barPaint = new Paint(); - private Paint circlePaint = new Paint(); - private Paint rimPaint = new Paint(); - private Paint textPaint = new Paint(); + // Text = "0%"; + Invalidate(); + } - // Rectangles - private RectF circleBounds = new RectF(); + /// + /// Stop spinning animation. + /// + public void StopSpinning() + { + IsSpinning = false; + _progress = 0; + _spinHandler.RemoveMessages(0); + } - private int progress = 0; - private bool isSpinning = false; - private SpinHandler spinHandler; + /// + /// Start spinning animation. + /// + public void Spin() + { + IsSpinning = true; + _spinHandler.SendEmptyMessage(0); + } - private Android.OS.BuildVersionCodes version = Android.OS.Build.VERSION.SdkInt; + /// + /// Increment progress by 1. + /// + public void IncrementProgress() + { + IsSpinning = false; + _progress++; + _spinHandler.SendEmptyMessage(0); + } - protected override void OnAttachedToWindow() + /// + /// Set progress. + /// + /// Amount to increase progress. + public void SetProgress(int amount) { - base.OnAttachedToWindow(); + IsSpinning = false; + var newProgress = (int)((float)amount / 100 * 360); - SetupBounds(); - SetupPaints(); + if (_version >= Android.OS.BuildVersionCodes.Honeycomb) + { + var va = + (Android.Animation.ValueAnimator)Android.Animation.ValueAnimator.OfInt(_progress, newProgress).SetDuration(250); - Invalidate(); - } + va.Update += (sender, e) => + { + _progress = (int)e.Animation.AnimatedValue; - void SetupPaints() - { - barPaint.Color = BarColor; - barPaint.AntiAlias = true; - barPaint.SetStyle(Paint.Style.Stroke); - barPaint.StrokeWidth = BarWidth; - - rimPaint.Color = RimColor; - rimPaint.AntiAlias = true; - rimPaint.SetStyle(Paint.Style.Stroke); - rimPaint.StrokeWidth = RimWidth; - - circlePaint.Color = CircleColor; - circlePaint.AntiAlias = true; - circlePaint.SetStyle(Paint.Style.Fill); - - textPaint.Color = TextColor; - textPaint.SetStyle(Paint.Style.Fill); - textPaint.AntiAlias = true; - textPaint.TextSize = TextSize; + Invalidate(); + }; + + va.Start(); + } + else + { + _progress = newProgress; + Invalidate(); + } + + _spinHandler.SendEmptyMessage(0); } - void SetupBounds() + /// + protected override void OnAttachedToWindow() { - circleBounds = - new RectF(WheelPaddingLeft + BarWidth, - WheelPaddingTop + BarWidth, - this.LayoutParameters.Width - WheelPaddingRight - BarWidth, - this.LayoutParameters.Height - WheelPaddingBottom - BarWidth); + base.OnAttachedToWindow(); + + SetupBounds(); + SetupPaints(); - fullRadius = (this.LayoutParameters.Width - WheelPaddingRight - BarWidth)/2; - CircleRadius = (fullRadius - BarWidth) + 1; + Invalidate(); } // ---------------------------------- // Animation stuff // ---------------------------------- + + /// protected override void OnDraw(Canvas canvas) { base.OnDraw(canvas); + if (!canvas.IsAlive()) + { + return; + } + // Draw the rim - canvas.DrawArc(circleBounds, 360, 360, false, rimPaint); + canvas.DrawArc(_circleBounds, 360, 360, false, _rimPaint); // Draw the bar - if (isSpinning) - canvas.DrawArc(circleBounds, progress - 90, BarLength, false, barPaint); + if (IsSpinning) + { + canvas.DrawArc(_circleBounds, _progress - 90, BarLength, false, _barPaint); + } else - canvas.DrawArc(circleBounds, -90, progress, false, barPaint); + { + canvas.DrawArc(_circleBounds, -90, _progress, false, _barPaint); + } // Draw the inner circle canvas.DrawCircle( - (circleBounds.Width() / 2) + RimWidth + WheelPaddingLeft, - (circleBounds.Height() / 2) + RimWidth + WheelPaddingTop, + (_circleBounds.Width() / 2) + RimWidth + WheelPaddingLeft, + (_circleBounds.Height() / 2) + RimWidth + WheelPaddingTop, CircleRadius, - circlePaint); - } - - public void ResetCount() - { - progress = 0; - // Text = "0%"; - Invalidate(); - } - - public void StopSpinning() - { - isSpinning = false; - progress = 0; - spinHandler.RemoveMessages(0); + _circlePaint); } - public void Spin() + private void SetupPaints() { - isSpinning = true; - spinHandler.SendEmptyMessage(0); + _barPaint.Color = BarColor; + _barPaint.AntiAlias = true; + _barPaint.SetStyle(Paint.Style.Stroke); + _barPaint.StrokeWidth = BarWidth; + + _rimPaint.Color = RimColor; + _rimPaint.AntiAlias = true; + _rimPaint.SetStyle(Paint.Style.Stroke); + _rimPaint.StrokeWidth = RimWidth; + + _circlePaint.Color = CircleColor; + _circlePaint.AntiAlias = true; + _circlePaint.SetStyle(Paint.Style.Fill); + + _textPaint.Color = TextColor; + _textPaint.SetStyle(Paint.Style.Fill); + _textPaint.AntiAlias = true; + _textPaint.TextSize = TextSize; } - public void IncrementProgress() + private void SetupBounds() { - isSpinning = false; - progress++; - spinHandler.SendEmptyMessage(0); - } - - public void SetProgress(int i) { - isSpinning = false; - var newProgress = (int)((float)i / (float)100 * (float)360); - - if (version >= Android.OS.BuildVersionCodes.Honeycomb) - { - Android.Animation.ValueAnimator va = - (Android.Animation.ValueAnimator)Android.Animation.ValueAnimator.OfInt(progress, newProgress).SetDuration(250); - - va.Update += (sender, e) => { - var interimValue = (int)e.Animation.AnimatedValue; - - progress = interimValue; - - Invalidate(); - }; - - va.Start(); - } - else - { - progress = newProgress; - Invalidate(); - } + _circleBounds = + new RectF( + WheelPaddingLeft + BarWidth, + WheelPaddingTop + BarWidth, + LayoutParameters.Width - WheelPaddingRight - BarWidth, + LayoutParameters.Height - WheelPaddingBottom - BarWidth); - spinHandler.SendEmptyMessage(0); + _fullRadius = (LayoutParameters.Width - WheelPaddingRight - BarWidth) / 2; + CircleRadius = (_fullRadius - BarWidth) + 1; } private class SpinHandler : Android.OS.Handler { - public SpinHandler(Action msgAction) : base() + public SpinHandler(Action msgAction) { MessageAction = msgAction; } diff --git a/AndHUD/XHUD.cs b/AndHUD/XHUD.cs index dce2408..6270b13 100644 --- a/AndHUD/XHUD.cs +++ b/AndHUD/XHUD.cs @@ -4,13 +4,15 @@ namespace XHUD { +#pragma warning disable SA1649 // File name should match first type name public static class HUD +#pragma warning restore SA1649 // File name should match first type name { public static Activity MyActivity { get; set; } public static void Show(string message, int progress = -1, MaskType maskType = MaskType.Black) { - AndHUD.Shared.Show(MyActivity, message, progress,(AndroidHUD.MaskType)maskType); + AndHUD.Shared.Show(MyActivity, message, progress, (AndroidHUD.MaskType)maskType); } public static void Dismiss() @@ -20,12 +22,12 @@ public static void Dismiss() public static void ShowToast(string message, bool showToastCentered = true, double timeoutMs = 1000) { - AndHUD.Shared.ShowToast(MyActivity, message, (AndroidHUD.MaskType)MaskType.Black, TimeSpan.FromSeconds(timeoutMs/1000), showToastCentered); + AndHUD.Shared.ShowToast(MyActivity, message, (AndroidHUD.MaskType)MaskType.Black, TimeSpan.FromSeconds(timeoutMs / 1000), showToastCentered); } public static void ShowToast(string message, MaskType maskType, bool showToastCentered = true, double timeoutMs = 1000) { - AndHUD.Shared.ShowToast(MyActivity, message, (AndroidHUD.MaskType)maskType, TimeSpan.FromSeconds(timeoutMs/1000), showToastCentered); + AndHUD.Shared.ShowToast(MyActivity, message, (AndroidHUD.MaskType)maskType, TimeSpan.FromSeconds(timeoutMs / 1000), showToastCentered); } } } diff --git a/Samples/SampleApp/MainActivity.cs b/Samples/SampleApp/MainActivity.cs index 09903e3..c2790c7 100644 --- a/Samples/SampleApp/MainActivity.cs +++ b/Samples/SampleApp/MainActivity.cs @@ -13,7 +13,8 @@ namespace SampleApp [Activity(Label = "@string/app_name", Theme = "@style/AppTheme.NoActionBar", MainLauncher = true)] public class MainActivity : AppCompatActivity { - private string[] _demos = new string[] { + private string[] _demos = new string[] + { "Status Indicator Only", "Status Indicator and Text", "Non-Modal Indicator and Text", @@ -34,6 +35,7 @@ public class MainActivity : AppCompatActivity private ListView _listView; + /// protected override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); @@ -49,6 +51,7 @@ protected override void OnCreate(Bundle savedInstanceState) _listView.ItemClick += OnItemClick; } + /// protected override void OnDestroy() { if (_listView != null) @@ -81,16 +84,16 @@ private void OnItemClick(object sender, AdapterView.ItemClickEventArgs e) ShowProgressDemo(progress => AndHUD.Shared.Show(this, "Loading... " + progress + "%", progress, MaskType.Clear)); break; case "Success Image Only": - AndHUD.Shared.ShowSuccessWithStatus(this, null, MaskType.Black, TimeSpan.FromSeconds(3)); + AndHUD.Shared.ShowSuccess(this, null, MaskType.Black, TimeSpan.FromSeconds(3)); break; case "Success Image and Text": - AndHUD.Shared.ShowSuccessWithStatus(this, "It Worked!", MaskType.Clear, TimeSpan.FromSeconds(3)); + AndHUD.Shared.ShowSuccess(this, "It Worked!", MaskType.Clear, TimeSpan.FromSeconds(3)); break; case "Error Image Only": - AndHUD.Shared.ShowErrorWithStatus(this, null, MaskType.Clear, TimeSpan.FromSeconds(3)); + AndHUD.Shared.ShowError(this, null, MaskType.Clear, TimeSpan.FromSeconds(3)); break; case "Error Image and Text": - AndHUD.Shared.ShowErrorWithStatus(this, "It no worked :(", MaskType.Black, TimeSpan.FromSeconds(3)); + AndHUD.Shared.ShowError(this, "It no worked :(", MaskType.Black, TimeSpan.FromSeconds(3)); break; case "Toast": AndHUD.Shared.ShowToast(this, "This is a toast... Cheers!", MaskType.Black, TimeSpan.FromSeconds(3), true); @@ -118,7 +121,8 @@ private void OnItemClick(object sender, AdapterView.ItemClickEventArgs e) private void ShowProgressDemo(Action action) { - Task.Run(() => { + _ = Task.Run(() => + { int progress = 0; while (progress <= 100) @@ -135,8 +139,8 @@ private void ShowProgressDemo(Action action) private void ShowDemo(Action action) { - Task.Run(() => { - + _ = Task.Run(() => + { action(); new ManualResetEvent(false).WaitOne(3000); From f4430c8a5ab1eeef4a66af89c400c6ab3dc6adfd Mon Sep 17 00:00:00 2001 From: Tomasz Cielecki Date: Tue, 15 Oct 2019 20:49:31 +0200 Subject: [PATCH 17/22] Don't error on file headers and missing docs --- analyzers.ruleset | 94 +++++++++++++++++++++-------------------------- 1 file changed, 42 insertions(+), 52 deletions(-) diff --git a/analyzers.ruleset b/analyzers.ruleset index 4761df9..14a5018 100644 --- a/analyzers.ruleset +++ b/analyzers.ruleset @@ -1,5 +1,5 @@  - + @@ -8,21 +8,15 @@ - - - - - - @@ -34,7 +28,6 @@ - @@ -88,6 +81,8 @@ + + @@ -95,58 +90,16 @@ - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -175,12 +128,15 @@ + + + @@ -188,25 +144,37 @@ + + + + + + + + + + + + @@ -219,22 +187,31 @@ + + + + + + + + + @@ -244,6 +221,7 @@ + @@ -252,6 +230,7 @@ + @@ -261,15 +240,21 @@ + + + + + + @@ -277,7 +262,12 @@ + + + + + - + \ No newline at end of file From 4dc75f5c8603f79020485bbb43f3de7153faf516 Mon Sep 17 00:00:00 2001 From: Tomasz Cielecki Date: Tue, 15 Oct 2019 20:54:37 +0200 Subject: [PATCH 18/22] Remove missing rule --- analyzers.ruleset | 1 - 1 file changed, 1 deletion(-) diff --git a/analyzers.ruleset b/analyzers.ruleset index 14a5018..7fb7c50 100644 --- a/analyzers.ruleset +++ b/analyzers.ruleset @@ -24,7 +24,6 @@ - From bd72412bd5516ffd1582710c0fdb24049a7da5e2 Mon Sep 17 00:00:00 2001 From: Tomasz Cielecki Date: Tue, 15 Oct 2019 20:54:46 +0200 Subject: [PATCH 19/22] Document enumerations --- AndHUD/MaskType.cs | 14 ++++++++++++++ AndHUD/XHUD.MaskType.cs | 10 ++++++++++ 2 files changed, 24 insertions(+) diff --git a/AndHUD/MaskType.cs b/AndHUD/MaskType.cs index bcb4f2e..0674578 100644 --- a/AndHUD/MaskType.cs +++ b/AndHUD/MaskType.cs @@ -1,9 +1,23 @@ namespace AndroidHUD { + /// + /// Mask type to determine how to dim the background. + /// public enum MaskType { + /// + /// No mask type + /// None = 1, + + /// + /// Show on top of clear background + /// Clear = 2, + + /// + /// Show on top of black dimmed background + /// Black = 3 } } diff --git a/AndHUD/XHUD.MaskType.cs b/AndHUD/XHUD.MaskType.cs index 9276ea1..ca8703b 100644 --- a/AndHUD/XHUD.MaskType.cs +++ b/AndHUD/XHUD.MaskType.cs @@ -1,8 +1,18 @@ namespace XHUD { + /// + /// MaskType which maps to . + /// public enum MaskType { + /// + /// Show on top of clear background + /// Clear = 2, + + /// + /// Show on top of black dimmed background + /// Black = 3, } } From 54943856d5d6473354aa022730e20a707ec9c0be Mon Sep 17 00:00:00 2001 From: Tomasz Cielecki Date: Tue, 15 Oct 2019 20:59:55 +0200 Subject: [PATCH 20/22] Add auto-generated comment to AssemblyInfo --- Samples/SampleApp/Properties/AssemblyInfo.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Samples/SampleApp/Properties/AssemblyInfo.cs b/Samples/SampleApp/Properties/AssemblyInfo.cs index 92d42db..15dac17 100644 --- a/Samples/SampleApp/Properties/AssemblyInfo.cs +++ b/Samples/SampleApp/Properties/AssemblyInfo.cs @@ -1,4 +1,5 @@ using System.Reflection; +// using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using Android.App; From 6d4caea9e9ba65d3425b6e328d680f0fb1297b25 Mon Sep 17 00:00:00 2001 From: Tomasz Cielecki Date: Tue, 15 Oct 2019 21:09:00 +0200 Subject: [PATCH 21/22] Also run build on PR --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e2d4835..8ff47a8 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,6 +1,6 @@ name: CI -on: [push] +on: [push, pull_request] jobs: build: From b70ad76f3232aeb25df982e327b8dfe6dbedbcf4 Mon Sep 17 00:00:00 2001 From: Tomasz Cielecki Date: Wed, 16 Oct 2019 08:51:52 +0200 Subject: [PATCH 22/22] Add more XML docs --- AndHUD/ProgressWheel.cs | 87 ++++++++++++++++++++++++++++++++++++----- AndHUD/XHUD.cs | 32 ++++++++++++++- 2 files changed, 107 insertions(+), 12 deletions(-) diff --git a/AndHUD/ProgressWheel.cs b/AndHUD/ProgressWheel.cs index 63341aa..dee0703 100644 --- a/AndHUD/ProgressWheel.cs +++ b/AndHUD/ProgressWheel.cs @@ -14,33 +14,48 @@ namespace AndroidHUD [Register("androidhud.ProgressWheel")] public class ProgressWheel : View { - // Sizes (with defaults) - private int _fullRadius = 100; + private readonly SpinHandler _spinHandler; + private readonly Android.OS.BuildVersionCodes _version = Android.OS.Build.VERSION.SdkInt; // Paints - private Paint _barPaint = new Paint(); - private Paint _circlePaint = new Paint(); - private Paint _rimPaint = new Paint(); - private Paint _textPaint = new Paint(); + private readonly Paint _barPaint = new Paint(); + private readonly Paint _circlePaint = new Paint(); + private readonly Paint _rimPaint = new Paint(); + private readonly Paint _textPaint = new Paint(); + + // Sizes (with defaults) + private int _fullRadius = 100; // Rectangles private RectF _circleBounds = new RectF(); - private int _progress = 0; - private SpinHandler _spinHandler; - - private Android.OS.BuildVersionCodes _version = Android.OS.Build.VERSION.SdkInt; + private int _progress; + /// + /// Create an instance of ProgressWheel. + /// + /// Android to create view from. public ProgressWheel(Context context) : this(context, null, 0) { } + /// + /// Create an instance of ProgressWheel, used by Android . + /// + /// Android to create view from. + /// Android XML attributes from the layout. public ProgressWheel(Context context, IAttributeSet attrs) : this(context, attrs, 0) { } + /// + /// Create an instance of ProgressWheel, used by Android . + /// + /// Android to create view from. + /// Android XML attributes from the layout. + /// Android style to apply to view. public ProgressWheel(Context context, IAttributeSet attrs, int defStyle) : base(context, attrs, defStyle) { @@ -86,42 +101,94 @@ public ProgressWheel(Context context, IAttributeSet attrs, int defStyle) }); } + /// + /// Get or set the radius of the circle to draw. Defaults to half of the + /// width of the view. + /// public int CircleRadius { get; set; } + /// + /// Get or set the length of the bar. + /// public int BarLength { get; set; } + /// + /// Get or set the width of the bar. + /// public int BarWidth { get; set; } + /// + /// Get or set the size of the text in px. + /// public int TextSize { get; set; } + /// + /// Get or set the top padding of the progress wheel. + /// public int WheelPaddingTop { get; set; } + /// + /// Get or set the bottom padding of the progress wheel. + /// public int WheelPaddingBottom { get; set; } + /// + /// Get or set the left padding of the progress wheel. + /// public int WheelPaddingLeft { get; set; } + /// + /// Get or set the right padding of the progress wheel. + /// public int WheelPaddingRight { get; set; } + /// + /// Gets or sets the color of the bar. + /// public Color BarColor { get; set; } + /// + /// Gets or sets the color of the circle. + /// public Color CircleColor { get; set; } + /// + /// Gets or sets the color of the rim. + /// public Color RimColor { get; set; } + /// + /// Gets or sets the shader of the rim. + /// public Shader RimShader { get => _rimPaint.Shader; set => _rimPaint.SetShader(value); } + /// + /// Gets or sets the text color. + /// public Color TextColor { get; set; } + /// + /// Gets or sets the spinning speed for the animation. + /// public int SpinSpeed { get; set; } + /// + /// Gets or sets the rim width. + /// public int RimWidth { get; set; } + /// + /// Gets or sets the delay in ms, between progress increases. + /// public int DelayMillis { get; set; } + /// + /// Gets whether the spinning animation is running. + /// public bool IsSpinning { get; private set; } /// diff --git a/AndHUD/XHUD.cs b/AndHUD/XHUD.cs index 6270b13..83eabab 100644 --- a/AndHUD/XHUD.cs +++ b/AndHUD/XHUD.cs @@ -4,30 +4,58 @@ namespace XHUD { + /// + /// HUD class to help interface between BTProgressHUD and AndHUD. + /// #pragma warning disable SA1649 // File name should match first type name public static class HUD #pragma warning restore SA1649 // File name should match first type name { + /// + /// Get or set Activity used as context to show dialog in. + /// public static Activity MyActivity { get; set; } + /// + /// Show a dialog. + /// + /// Message to show under loading indicator. + /// If set between 1 and 100, the progress will be determinate. + /// Mask type used to dim background of dialog. public static void Show(string message, int progress = -1, MaskType maskType = MaskType.Black) { AndHUD.Shared.Show(MyActivity, message, progress, (AndroidHUD.MaskType)maskType); } + /// + /// Dismiss currently shown dialog. + /// public static void Dismiss() { AndHUD.Shared.Dismiss(MyActivity); } + /// + /// Show toast message. + /// + /// Message to show in toast. + /// If true, toast will be centered on screen. Otherwise towards bottom of screen. + /// Timeout in ms. Determines when to dismiss the toast. public static void ShowToast(string message, bool showToastCentered = true, double timeoutMs = 1000) { - AndHUD.Shared.ShowToast(MyActivity, message, (AndroidHUD.MaskType)MaskType.Black, TimeSpan.FromSeconds(timeoutMs / 1000), showToastCentered); + AndHUD.Shared.ShowToast(MyActivity, message, (AndroidHUD.MaskType)MaskType.Black, TimeSpan.FromMilliseconds(timeoutMs), showToastCentered); } + /// + /// Show toast message. + /// + /// Message to show in toast. + /// Mask type used to dim background of dialog. + /// If true, toast will be centered on screen. Otherwise towards bottom of screen. + /// Timeout in ms. Determines when to dismiss the toast. public static void ShowToast(string message, MaskType maskType, bool showToastCentered = true, double timeoutMs = 1000) { - AndHUD.Shared.ShowToast(MyActivity, message, (AndroidHUD.MaskType)maskType, TimeSpan.FromSeconds(timeoutMs / 1000), showToastCentered); + AndHUD.Shared.ShowToast(MyActivity, message, (AndroidHUD.MaskType)maskType, TimeSpan.FromMilliseconds(timeoutMs), showToastCentered); } } }