diff --git a/Pixiview.iOS/Pixiview.iOS.csproj b/Pixiview.iOS/Pixiview.iOS.csproj index 3d7a376..dc9916f 100644 --- a/Pixiview.iOS/Pixiview.iOS.csproj +++ b/Pixiview.iOS/Pixiview.iOS.csproj @@ -75,7 +75,7 @@ - + diff --git a/Pixiview.iOS/Renderers/AdaptedNavigationPageRenderer.cs b/Pixiview.iOS/Renderers/AdaptedNavigationPageRenderer.cs new file mode 100644 index 0000000..e4b9d87 --- /dev/null +++ b/Pixiview.iOS/Renderers/AdaptedNavigationPageRenderer.cs @@ -0,0 +1,26 @@ +using Pixiview.iOS.Renderers; +using Pixiview.UI; +using UIKit; +using Xamarin.Forms; +using Xamarin.Forms.Platform.iOS; + +[assembly: ExportRenderer(typeof(AdaptedNavigationPage), typeof(AdaptedNavigationPageRenderer))] +namespace Pixiview.iOS.Renderers +{ + public class AdaptedNavigationPageRenderer : NavigationRenderer + { + public override void WillMoveToParentViewController(UIViewController parent) + { + if (Element is AdaptedNavigationPage navigation) + { + NavigationBar.Translucent = true; + + var barHeight = NavigationBar.Frame.Height; + var statusHeight = UIApplication.SharedApplication.StatusBarFrame.Height; + navigation.SetNavigationBarHeight(barHeight, statusHeight); + } + + base.WillMoveToParentViewController(parent); + } + } +} diff --git a/Pixiview.iOS/Renderers/AdaptedPageRenderer.cs b/Pixiview.iOS/Renderers/AdaptedPageRenderer.cs index ce1f434..df6b31c 100644 --- a/Pixiview.iOS/Renderers/AdaptedPageRenderer.cs +++ b/Pixiview.iOS/Renderers/AdaptedPageRenderer.cs @@ -24,10 +24,21 @@ namespace Pixiview.iOS.Renderers //var mode = ForPage.GetLargeTitleDisplay(page); //NavigationItem.LargeTitleDisplayMode = UINavigationItemLargeTitleDisplayMode.Automatic; + page.InitOrientation((Orientation)UIDevice.CurrentDevice.Orientation); page.OnLoad(); } } + protected override void Dispose(bool disposing) + { + if (Element is AdaptedPage page) + { + page.OnUnload(); + } + + base.Dispose(disposing); + } + public override bool PrefersHomeIndicatorAutoHidden => Screen.GetHomeIndicatorAutoHidden(Element); public override void ViewDidAppear(bool animated) diff --git a/Pixiview.iOS/Renderers/NavigationPageRenderer.cs b/Pixiview.iOS/Renderers/NavigationPageRenderer.cs deleted file mode 100644 index e4580c0..0000000 --- a/Pixiview.iOS/Renderers/NavigationPageRenderer.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Pixiview.iOS.Renderers; -using UIKit; -using Xamarin.Forms; -using Xamarin.Forms.Platform.iOS; - -[assembly: ExportRenderer(typeof(NavigationPage), typeof(NavigationPageRenderer))] -namespace Pixiview.iOS.Renderers -{ - public class NavigationPageRenderer : NavigationRenderer - { - public override void WillMoveToParentViewController(UIViewController parent) - { - NavigationBar.Translucent = true; - - base.WillMoveToParentViewController(parent); - } - } -} diff --git a/Pixiview/MainPage.xaml b/Pixiview/MainPage.xaml index e0308f8..a24ee7d 100644 --- a/Pixiview/MainPage.xaml +++ b/Pixiview/MainPage.xaml @@ -13,12 +13,6 @@ BackgroundColor="{DynamicResource WindowColor}" Title="{r:Text Follow}" OrientationChanged="Page_OrientationChanged"> - @@ -84,7 +78,7 @@ \ No newline at end of file diff --git a/Pixiview/MainPage.xaml.cs b/Pixiview/MainPage.xaml.cs index 4122f0c..c3756d6 100644 --- a/Pixiview/MainPage.xaml.cs +++ b/Pixiview/MainPage.xaml.cs @@ -29,7 +29,6 @@ namespace Pixiview private static void OnLoadingPropertyChanged(BindableObject obj, object oldValue, object newValue) { var page = (MainPage)obj; - var before = (bool)oldValue; var now = (bool)newValue; if (!page.loaded && now && Stores.NetworkAvailable) { @@ -64,9 +63,9 @@ namespace Pixiview public MainPage() { + BindingContext = this; InitializeComponent(); - BindingContext = this; commandIllustImageTapped = new Command(OnIllustImageTapped); } @@ -75,6 +74,10 @@ namespace Pixiview public override void OnLoad() { App.DebugPrint($"folder: {Stores.PersonalFolder}"); + if (!loaded) + { + Loading = true; + } } protected override void OnAppearing() @@ -82,10 +85,6 @@ namespace Pixiview base.OnAppearing(); Connectivity.ConnectivityChanged += Connectivity_ConnectivityChanged; - if (!loaded) - { - Loading = true; - } } protected override void OnDisappearing() @@ -197,8 +196,17 @@ namespace Pixiview case Orientation.Portrait: Columns = 2; break; - case Orientation.Unknown: case Orientation.PortraitUpsideDown: + if (DeviceInfo.Idiom == DeviceIdiom.Phone) + { + Columns = 4; + } + else + { + Columns = 2; + } + break; + case Orientation.Unknown: case Orientation.LandscapeLeft: case Orientation.LandscapeRight: default: diff --git a/Pixiview/UI/AdaptedNavigationPage.cs b/Pixiview/UI/AdaptedNavigationPage.cs new file mode 100644 index 0000000..f69235b --- /dev/null +++ b/Pixiview/UI/AdaptedNavigationPage.cs @@ -0,0 +1,16 @@ +using Xamarin.Forms; + +namespace Pixiview.UI +{ + public class AdaptedNavigationPage : NavigationPage + { + public AdaptedNavigationPage(Page page) : base(page) + { + } + + public void SetNavigationBarHeight(double barHeight, double statusHeight) + { + StyleDefinition.SetNavigationBarHeight(barHeight, statusHeight); + } + } +} diff --git a/Pixiview/UI/AdaptedPage.cs b/Pixiview/UI/AdaptedPage.cs index 37d4490..4638b06 100644 --- a/Pixiview/UI/AdaptedPage.cs +++ b/Pixiview/UI/AdaptedPage.cs @@ -17,7 +17,10 @@ namespace Pixiview.UI set => SetValue(StatusBarPaddingProperty, value); } + public Orientation CurrentOrientation { get; private set; } + public event EventHandler Load; + public event EventHandler Unload; public event EventHandler OrientationChanged; public virtual void OnLoad() @@ -25,6 +28,11 @@ namespace Pixiview.UI Load?.Invoke(this, EventArgs.Empty); } + public virtual void OnUnload() + { + Unload?.Invoke(this, EventArgs.Empty); + } + public virtual void OnOrientationChanged(Orientation orientation) { if (orientation == Orientation.LandscapeLeft || orientation == Orientation.PortraitUpsideDown) @@ -43,6 +51,11 @@ namespace Pixiview.UI OrientationChanged?.Invoke(this, new OrientationEventArgs { CurrentOrientation = orientation }); } + public void InitOrientation(Orientation orientation) + { + CurrentOrientation = orientation; + } + protected void Start(Action action) { if (Tap.IsBusy) diff --git a/Pixiview/UI/StyleDefinition.cs b/Pixiview/UI/StyleDefinition.cs index cb8e284..950df87 100644 --- a/Pixiview/UI/StyleDefinition.cs +++ b/Pixiview/UI/StyleDefinition.cs @@ -9,13 +9,41 @@ namespace Pixiview.UI public const double FontSizeTitle = 18.0; public const double FontSizeTitleIcon = 24.0; + public static readonly Thickness ScreenBottomPadding; public static readonly Thickness HorizonLeft10 = new Thickness(10, 0, 0, 0); public static readonly Thickness HorizonRight10 = new Thickness(0, 0, 10, 0); public static readonly Thickness LeftBottom10 = new Thickness(10, 0, 0, 10); public static readonly GridLength TitleIconWidth = 40; + public static Thickness NavigationBarOffset; + public static Thickness StatusBarOffset; + public static Thickness TotalBarOffset; + public const string IconLayer = "\uf302"; public const string IconOption = "\uf013"; + public const string IconDownload = "\uf019"; + + static StyleDefinition() + { + if (IsFullscreenDevice) + { + if (DeviceInfo.Idiom == DeviceIdiom.Phone) + { + ScreenBottomPadding = new Thickness(0, 0, 0, 26); + } + else + { + ScreenBottomPadding = new Thickness(0, 0, 0, 16); + } + } + } + + public static void SetNavigationBarHeight(double barHeight, double statusHeight) + { + NavigationBarOffset = new Thickness(0, barHeight, 0, 0); + StatusBarOffset = new Thickness(0, statusHeight, 0, 0); + TotalBarOffset = new Thickness(0, barHeight + statusHeight, 0, 0); + } private static bool? _isFullscreenDevice; public static bool IsFullscreenDevice diff --git a/Pixiview/UI/Theme/DarkTheme.cs b/Pixiview/UI/Theme/DarkTheme.cs index d025e2e..b35e791 100644 --- a/Pixiview/UI/Theme/DarkTheme.cs +++ b/Pixiview/UI/Theme/DarkTheme.cs @@ -34,6 +34,7 @@ namespace Pixiview.UI.Theme Add(MainColor, Color.FromRgb(0x33, 0x33, 0x33)); Add(MainTextColor, Color.White); Add(SubColor, Color.FromRgb(0x33, 0x33, 0x33)); + Add(MaskColor, Color.FromRgba(0xff, 0xff, 0xff, 0x50)); } } } diff --git a/Pixiview/UI/Theme/LightTheme.cs b/Pixiview/UI/Theme/LightTheme.cs index 1174b60..1595721 100644 --- a/Pixiview/UI/Theme/LightTheme.cs +++ b/Pixiview/UI/Theme/LightTheme.cs @@ -34,6 +34,7 @@ namespace Pixiview.UI.Theme Add(MainColor, Color.FromRgb(0xf0, 0xf0, 0xf0)); // Color.FromRgb(0x7f, 0x99, 0xc6) Add(MainTextColor, Color.Black); Add(SubColor, Color.FromRgb(0xf0, 0xf0, 0xf0)); // Color.FromRgb(0xfa, 0xfa, 0xf0) + Add(MaskColor, Color.FromRgba(0, 0, 0, 0x50)); } } } diff --git a/Pixiview/UI/Theme/ThemeBase.cs b/Pixiview/UI/Theme/ThemeBase.cs index f6a0350..98a03c7 100644 --- a/Pixiview/UI/Theme/ThemeBase.cs +++ b/Pixiview/UI/Theme/ThemeBase.cs @@ -7,6 +7,7 @@ namespace Pixiview.UI.Theme public const string TitleButton = nameof(TitleButton); public const string TitleLabel = nameof(TitleLabel); public const string FontIconOption = nameof(FontIconOption); + public const string FontIconDownload = nameof(FontIconDownload); public const string StatusBarStyle = nameof(StatusBarStyle); public const string WindowColor = nameof(WindowColor); @@ -15,6 +16,7 @@ namespace Pixiview.UI.Theme public const string MainColor = nameof(MainColor); public const string MainTextColor = nameof(MainTextColor); public const string SubColor = nameof(SubColor); + public const string MaskColor = nameof(MaskColor); public const string IconLightFontFamily = nameof(IconLightFontFamily); public const string IconRegularFontFamily = nameof(IconRegularFontFamily); @@ -23,14 +25,19 @@ namespace Pixiview.UI.Theme public const string FontSizeTitle = nameof(FontSizeTitle); public const string FontSizeTitleIcon = nameof(FontSizeTitleIcon); //public const string Horizon10 = nameof(Horizon10); + public const string ScreenBottomPadding = nameof(ScreenBottomPadding); + public const string NavigationBarHeight = nameof(NavigationBarHeight); public const string IconOption = nameof(IconOption); + public const string IconDownload = nameof(IconDownload); protected void InitResources() { Add(FontSizeTitle, StyleDefinition.FontSizeTitle); Add(FontSizeTitleIcon, StyleDefinition.FontSizeTitleIcon); //Add(Horizon10, StyleDefinition.Horizon10); + Add(ScreenBottomPadding, StyleDefinition.ScreenBottomPadding); Add(IconOption, StyleDefinition.IconOption); + Add(IconDownload, StyleDefinition.IconDownload); if (App.ExtraResources != null) { @@ -40,6 +47,9 @@ namespace Pixiview.UI.Theme } } + var mainColor = this[MainTextColor]; + var iconSolidFontFamily = (string)this[IconSolidFontFamily]; + Add(TitleLabel, new Style(typeof(Label)) { Setters = @@ -48,27 +58,34 @@ namespace Pixiview.UI.Theme new Setter { Property = View.HorizontalOptionsProperty, Value = LayoutOptions.Fill }, new Setter { Property = Label.HorizontalTextAlignmentProperty, Value = TextAlignment.Center }, new Setter { Property = Label.FontSizeProperty, Value = StyleDefinition.FontSizeTitle }, - new Setter { Property = Label.TextColorProperty, Value = this[MainTextColor] } + new Setter { Property = Label.TextColorProperty, Value = mainColor } } }); + Add(TitleButton, new Style(typeof(Button)) { Setters = { new Setter { Property = Button.BorderWidthProperty, Value = 0.0 }, new Setter { Property = VisualElement.BackgroundColorProperty, Value = Color.Transparent }, - new Setter { Property = Button.FontFamilyProperty, Value = this[IconSolidFontFamily] }, + new Setter { Property = Button.FontFamilyProperty, Value = iconSolidFontFamily }, new Setter { Property = Button.FontSizeProperty, Value = StyleDefinition.FontSizeTitleIcon }, - new Setter { Property = Button.TextColorProperty, Value = this[MainTextColor] } + new Setter { Property = Button.TextColorProperty, Value = mainColor } } }); Add(FontIconOption, new FontImageSource { - FontFamily = (string)this[IconSolidFontFamily], + FontFamily = iconSolidFontFamily, Glyph = StyleDefinition.IconOption, Size = StyleDefinition.FontSizeTitle }); + Add(FontIconDownload, new FontImageSource + { + FontFamily = iconSolidFontFamily, + Glyph = StyleDefinition.IconDownload, + Size = StyleDefinition.FontSizeTitle + }); } } } diff --git a/Pixiview/Utils/UIFactory.cs b/Pixiview/Utils/UIFactory.cs index c66e38b..1e30d7b 100644 --- a/Pixiview/Utils/UIFactory.cs +++ b/Pixiview/Utils/UIFactory.cs @@ -1,13 +1,14 @@ -using Pixiview.UI.Theme; +using Pixiview.UI; +using Pixiview.UI.Theme; using Xamarin.Forms; namespace Pixiview.Utils { public static class UIFactory { - public static NavigationPage CreateNavigationPage(Page root) + public static AdaptedNavigationPage CreateNavigationPage(Page root) { - var navigation = new NavigationPage(root); + var navigation = new AdaptedNavigationPage(root); //navigation.SetDynamicResource(NavigationPage.BarBackgroundColorProperty, ThemeBase.MainColor); navigation.SetDynamicResource(NavigationPage.BarTextColorProperty, ThemeBase.MainTextColor); navigation.SetDynamicResource(VisualElement.BackgroundColorProperty, ThemeBase.WindowColor); diff --git a/Pixiview/ViewIllustPage.xaml b/Pixiview/ViewIllustPage.xaml index f9932c8..3025028 100644 --- a/Pixiview/ViewIllustPage.xaml +++ b/Pixiview/ViewIllustPage.xaml @@ -1,6 +1,7 @@  + Title="{r:Text Preview}" + OrientationChanged="Page_OrientationChanged"> + + + + + + + + + + + + + + + + + diff --git a/Pixiview/ViewIllustPage.xaml.cs b/Pixiview/ViewIllustPage.xaml.cs index 2ef1772..c8bd921 100644 --- a/Pixiview/ViewIllustPage.xaml.cs +++ b/Pixiview/ViewIllustPage.xaml.cs @@ -1,18 +1,141 @@ -using System; -using System.Collections.Generic; +using System; using Pixiview.UI; +using Pixiview.UI.Theme; +using Xamarin.Essentials; using Xamarin.Forms; namespace Pixiview { public partial class ViewIllustPage : AdaptedPage { - private readonly IllustItem illust; + public static readonly BindableProperty IllustsProperty = BindableProperty.Create( + nameof(Illusts), typeof(IllustDetailItem[]), typeof(ViewIllustPage)); + public static readonly BindableProperty PagePositionTextProperty = BindableProperty.Create( + nameof(PagePositionText), typeof(string), typeof(ViewIllustPage)); + public static readonly BindableProperty IsPageVisibleProperty = BindableProperty.Create( + nameof(IsPageVisible), typeof(bool), typeof(ViewIllustPage)); + public static readonly BindableProperty PageTopMarginProperty = BindableProperty.Create( + nameof(PageTopMargin), typeof(Thickness), typeof(ViewIllustPage)); + public static readonly BindableProperty IllustItemProperty = BindableProperty.Create( + nameof(IllustItem), typeof(IllustItem), typeof(ViewIllustPage)); + + public IllustDetailItem[] Illusts + { + get => (IllustDetailItem[])GetValue(IllustsProperty); + set => SetValue(IllustsProperty, value); + } + public string PagePositionText + { + get => (string)GetValue(PagePositionTextProperty); + set => SetValue(PagePositionTextProperty, value); + } + public bool IsPageVisible + { + get => (bool)GetValue(IsPageVisibleProperty); + set => SetValue(IsPageVisibleProperty, value); + } + public Thickness PageTopMargin + { + get => (Thickness)GetValue(PageTopMarginProperty); + set => SetValue(PageTopMarginProperty, value); + } + public IllustItem IllustItem + { + get => (IllustItem)GetValue(IllustItemProperty); + private set => SetValue(IllustItemProperty, value); + } public ViewIllustPage(IllustItem illust) { - this.illust = illust; + IllustItem = illust; + BindingContext = this; + InitializeComponent(); } + + public override void OnLoad() + { + var illust = IllustItem; + if (illust == null) + { + return; + } + + var items = new IllustDetailItem[illust.PageCount]; + if (items.Length > 0) + { + IsPageVisible = true; + PagePositionText = $"1/{items.Length}"; + } + + items[0] = new IllustDetailItem + { + Image = illust.Image, + Loading = true + }; + + Illusts = items; + UpdatePageTopMargin(CurrentOrientation); + } + + private void CarouselView_PositionChanged(object sender, PositionChangedEventArgs e) + { + PagePositionText = $"{e.CurrentPosition + 1}/{Illusts.Length}"; + } + + private void Page_OrientationChanged(object sender, OrientationEventArgs e) + { + UpdatePageTopMargin(e.CurrentOrientation); + } + + private void UpdatePageTopMargin(Orientation orientation) + { + switch (orientation) + { + case Orientation.Portrait: + PageTopMargin = StyleDefinition.TotalBarOffset; + break; + case Orientation.PortraitUpsideDown: + if (DeviceInfo.Idiom == DeviceIdiom.Phone) + { + PageTopMargin = StyleDefinition.NavigationBarOffset; + } + else + { + PageTopMargin = StyleDefinition.TotalBarOffset; + } + break; + case Orientation.Unknown: + case Orientation.LandscapeLeft: + case Orientation.LandscapeRight: + default: + PageTopMargin = StyleDefinition.NavigationBarOffset; + break; + } + } + + private void Download_Clicked(object sender, EventArgs e) + { + + } + } + + public class IllustDetailItem : BindableObject + { + public static readonly BindableProperty ImageProperty = BindableProperty.Create( + nameof(Image), typeof(ImageSource), typeof(IllustDetailItem)); + public static readonly BindableProperty LoadingProperty = BindableProperty.Create( + nameof(Loading), typeof(bool), typeof(IllustDetailItem)); + + public ImageSource Image + { + get => (ImageSource)GetValue(ImageProperty); + set => SetValue(ImageProperty, value); + } + public bool Loading + { + get => (bool)GetValue(LoadingProperty); + set => SetValue(LoadingProperty, value); + } } }