217 lines
8.4 KiB
C#
217 lines
8.4 KiB
C#
#if __ANDROID_21__
|
|
using Xamarin.Forms.Platform.Android;
|
|
#endif
|
|
using System.Globalization;
|
|
using System.Threading;
|
|
using Gallery.Resources;
|
|
using Gallery.Util;
|
|
using Xamarin.Forms;
|
|
|
|
namespace Gallery.Services
|
|
{
|
|
public class Environment
|
|
{
|
|
private static readonly CultureInfo DefaultCulture = new("zh-CN");
|
|
|
|
#if __ANDROID_21__
|
|
public static void SetStatusBarColor(Color color)
|
|
{
|
|
if (Android.OS.Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.Lollipop)
|
|
{
|
|
Android.OS.Droid.MainActivity.Main.SetStatusBarColor(color.ToAndroid());
|
|
Android.OS.Droid.MainActivity.Main.Window.DecorView.SystemUiVisibility =
|
|
App.CurrentTheme == Xamarin.Essentials.AppTheme.Dark ?
|
|
Android.Views.StatusBarVisibility.Visible :
|
|
(Android.Views.StatusBarVisibility)Android.Views.SystemUiFlags.LightStatusBar;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
public static void SetStatusBarStyle(StatusBarStyles style)
|
|
{
|
|
#if __IOS__
|
|
SetStatusBarStyle(ConvertStyle(style));
|
|
}
|
|
|
|
public static void SetStatusBarStyle(UIKit.UIStatusBarStyle style)
|
|
{
|
|
if (UIKit.UIApplication.SharedApplication.StatusBarStyle == style)
|
|
{
|
|
return;
|
|
}
|
|
if (style == UIKit.UIStatusBarStyle.BlackOpaque)
|
|
{
|
|
UIKit.UIApplication.SharedApplication.SetStatusBarHidden(true, true);
|
|
}
|
|
else
|
|
{
|
|
if (UIKit.UIApplication.SharedApplication.StatusBarHidden)
|
|
{
|
|
UIKit.UIApplication.SharedApplication.SetStatusBarStyle(style, false);
|
|
UIKit.UIApplication.SharedApplication.SetStatusBarHidden(false, true);
|
|
}
|
|
else
|
|
{
|
|
UIKit.UIApplication.SharedApplication.SetStatusBarStyle(style, true);
|
|
}
|
|
}
|
|
}
|
|
|
|
public static UIKit.UIStatusBarStyle ConvertStyle(StatusBarStyles style)
|
|
{
|
|
return style switch
|
|
{
|
|
StatusBarStyles.DarkText => UIKit.UIStatusBarStyle.DarkContent,
|
|
StatusBarStyles.WhiteText => UIKit.UIStatusBarStyle.LightContent,
|
|
StatusBarStyles.Hidden => UIKit.UIStatusBarStyle.BlackOpaque,
|
|
_ => UIKit.UIStatusBarStyle.Default,
|
|
};
|
|
#endif
|
|
}
|
|
|
|
public static void SetCultureInfo(CultureInfo ci)
|
|
{
|
|
Thread.CurrentThread.CurrentCulture = ci;
|
|
Thread.CurrentThread.CurrentUICulture = ci;
|
|
#if DEBUG
|
|
Log.Print($"CurrentCulture set: {ci.Name}");
|
|
#endif
|
|
}
|
|
|
|
public static CultureInfo GetCurrentCultureInfo()
|
|
{
|
|
string lang;
|
|
|
|
#if __IOS__
|
|
if (Foundation.NSLocale.PreferredLanguages.Length > 0)
|
|
{
|
|
var pref = Foundation.NSLocale.PreferredLanguages[0];
|
|
lang = ToDotnetLanguage(pref);
|
|
}
|
|
else
|
|
{
|
|
lang = "zh-CN";
|
|
}
|
|
#elif __ANDROID__
|
|
var locale = Java.Util.Locale.Default;
|
|
lang = ToDotnetLanguage(locale.ToString().Replace('_', '-'));
|
|
#endif
|
|
|
|
CultureInfo ci;
|
|
var platform = new PlatformCulture(lang);
|
|
try
|
|
{
|
|
ci = new CultureInfo(platform.Language);
|
|
}
|
|
catch (CultureNotFoundException e)
|
|
{
|
|
try
|
|
{
|
|
var fallback = ToDotnetFallbackLanguage(platform);
|
|
Log.Print($"{lang} failed, trying {fallback} ({e.Message})");
|
|
ci = new CultureInfo(fallback);
|
|
}
|
|
catch (CultureNotFoundException e1)
|
|
{
|
|
Log.Error("culture.get", $"{lang} couldn't be set, using 'zh-CN' ({e1.Message})");
|
|
ci = DefaultCulture;
|
|
}
|
|
}
|
|
|
|
return ci;
|
|
}
|
|
|
|
#if __IOS__
|
|
private static string ToDotnetLanguage(string iOSLanguage)
|
|
{
|
|
//certain languages need to be converted to CultureInfo equivalent
|
|
string netLanguage = iOSLanguage switch
|
|
{
|
|
// "Malaysian (Malaysia)" not supported .NET culture
|
|
// "Malaysian (Singapore)" not supported .NET culture
|
|
"ms-MY" or "ms-SG" => "ms", // closest supported
|
|
// "Schwiizertüütsch (Swiss German)" not supported .NET culture
|
|
"gsw-CH" => "de-CH", // closest supported
|
|
// add more application-specific cases here (if required)
|
|
// ONLY use cultures that have been tested and known to work
|
|
_ => iOSLanguage
|
|
};
|
|
|
|
#if DEBUG
|
|
Log.Print($"iOS Language: {iOSLanguage}, .NET Language/Locale: {netLanguage}");
|
|
#endif
|
|
return netLanguage;
|
|
}
|
|
#elif __ANDROID__
|
|
private static string ToDotnetLanguage(string androidLanguage)
|
|
{
|
|
//certain languages need to be converted to CultureInfo equivalent
|
|
string netLanguage = androidLanguage switch
|
|
{
|
|
// "Malaysian (Brunei)" not supported .NET culture
|
|
// "Malaysian (Malaysia)" not supported .NET culture
|
|
// "Malaysian (Singapore)" not supported .NET culture
|
|
"ms-BN" or "ms-MY" or "ms-SG" => "ms", // closest supported
|
|
// "Indonesian (Indonesia)" has different code in .NET
|
|
"in-ID" => "id-ID", // correct code for .NET
|
|
// "Schwiizertüütsch (Swiss German)" not supported .NET culture
|
|
"gsw-CH" => "de-CH", // closest supported
|
|
// add more application-specific cases here (if required)
|
|
// ONLY use cultures that have been tested and known to work
|
|
_ => androidLanguage
|
|
};
|
|
|
|
#if DEBUG
|
|
Log.Print($"Android Language: {androidLanguage}, .NET Language/Locale: {netLanguage}");
|
|
#endif
|
|
return netLanguage;
|
|
}
|
|
#endif
|
|
|
|
private static string ToDotnetFallbackLanguage(PlatformCulture platCulture)
|
|
{
|
|
string netLanguage = platCulture.LanguageCode switch
|
|
{
|
|
"pt" => "pt-PT", // fallback to Portuguese (Portugal)
|
|
"gsw" => "de-CH", // equivalent to German (Switzerland) for this app
|
|
// add more application-specific cases here (if required)
|
|
// ONLY use cultures that have been tested and known to work
|
|
_ => platCulture.LanguageCode // use the first part of the identifier (two chars, usually);
|
|
};
|
|
|
|
#if DEBUG
|
|
Log.Print($".NET Fallback Language/Locale: {platCulture.LanguageCode} to {netLanguage} (application-specific)");
|
|
#endif
|
|
return netLanguage;
|
|
}
|
|
}
|
|
|
|
public static class Screen
|
|
{
|
|
private const string StatusBarStyle = nameof(StatusBarStyle);
|
|
private const string HomeIndicatorAutoHidden = nameof(HomeIndicatorAutoHidden);
|
|
|
|
public static readonly BindableProperty StatusBarStyleProperty = BindableProperty.CreateAttached(StatusBarStyle, typeof(StatusBarStyles), typeof(Page), StatusBarStyles.WhiteText);
|
|
public static StatusBarStyles GetStatusBarStyle(VisualElement page) => (StatusBarStyles)page.GetValue(StatusBarStyleProperty);
|
|
public static void SetStatusBarStyle(VisualElement page, StatusBarStyles value) => page.SetValue(StatusBarStyleProperty, value);
|
|
|
|
public static readonly BindableProperty HomeIndicatorAutoHiddenProperty = BindableProperty.CreateAttached(HomeIndicatorAutoHidden, typeof(bool), typeof(Shell), false);
|
|
public static bool GetHomeIndicatorAutoHidden(VisualElement page) => (bool)page.GetValue(HomeIndicatorAutoHiddenProperty);
|
|
public static void SetHomeIndicatorAutoHidden(VisualElement page, bool value) => page.SetValue(HomeIndicatorAutoHiddenProperty, value);
|
|
}
|
|
|
|
public enum StatusBarStyles
|
|
{
|
|
Default,
|
|
// Will behave as normal.
|
|
// White text on black NavigationBar/in iOS Dark mode and
|
|
// Black text on white NavigationBar/in iOS Light mode
|
|
DarkText,
|
|
// Will switch the color of content of StatusBar to black.
|
|
WhiteText,
|
|
// Will switch the color of content of StatusBar to white.
|
|
Hidden
|
|
// Will hide the StatusBar
|
|
}
|
|
}
|