diff --git a/README.md b/README.md
index 16478a2..dae0339 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,484 @@
-# SimpleShell
\ No newline at end of file
+# SimpleToolkit
+
+SimpleToolkit is a .NET MAUI library of helpers and simple, easily customizable controls.
+
+The library consists of three packages:
+
+- [SimpleToolkit.Core](#simpletoolkitcore)
+
+- [SimpleToolkit.SimpleShell](#simpletoolkitsimpleshell)
+
+- [SimpleToolkit.SimpleShell.Controls](#simpletoolkitsimpleshellcontrols)
+
+> ⚠ **Warning:** Long-term support is not guaranteed. Use at your own risk.
+
+## Samples
+
+Here are some of my samples that were built using this library:
+
+
+
+
+
+ Gadget Store App
+
+
+
+
+
+
+
+ Navbar Animation #1
+
+
+
+
+
+
+
+ Navbar Animation #2
+
+
+## SimpleToolkit.Core
+
+[](https://www.nuget.org/packages/SimpleToolkit.Core/)
+
+The *SimpleToolkit.Core* package is a set of simple .NET MAUI controls and helpers.
+
+### Getting Started
+
+In order to use *SimpleToolkit.Core*, you need to call the `UseSimpleToolkit()` extension method in your `MauiProgram.cs` file:
+
+```csharp
+builder.UseSimpleToolkit();
+```
+
+### Icon
+
+Thanks to the `Icon` control, you are able to display a tinted image:
+
+```xml
+
+
+
+```
+
+Output:
+
+
+
+
+
+#### Implementation details
+
+The `Icon` class is inherited from the .NET MAUI `Image` class, but behind the scenes it is implemented in the same way as .NET MAUI `Image` only on Android and iOS. WinUI implementation is based on `BitmapIcon` and `FontIcon` controls. Because of that, the control supports only these image sources on Windows:
+
+- `FileImageSource`
+- `UriImageSource`
+- `FontImageSource`
+
+These `Image` properties are not supported at all:
+
+- `Aspect` - the default behavior is `AspectFit`
+- `IsAnimationPlaying`
+- `IsLoading`
+- `IsOpaque`
+
+### ContentButton
+
+`ContentButton` is just a button that can hold whatever content you want:
+
+```xml
+
+
+
+
+
+
+
+
+
+
+
+```
+
+Output:
+
+
+
+
+
+#### Implementation details
+
+The `ContentButton` class is inherited from the .NET MAUI `ContentView` control. `ContentButton` has these events in addition to `ContentView`s events and properties:
+
+- `Clicked` - an event that fires when the button is clicked
+- `Pressed` - an event that fires when the button is pressed
+- `Released` - an event that fires when the button is released
+
+### Popover
+
+`Popover` allows you to display custom popovers (flyouts) anchored to any control:
+
+```xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+Code behind:
+
+```csharp
+private void ButtonClicked(object sender, EventArgs e)
+{
+ var button = sender as Button;
+
+ button.ShowAttachedPopover();
+}
+```
+
+Output:
+
+
+
+
+
+ Android
+
+
+ iOS
+
+
+ Windows
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#### Implementation details
+
+The `Popover` class is inherited from the .NET MAUI `Element` class. `Popover` offers these properties and methods in addition to `Element`s properties and methods:
+
+- `Content` - the popover content of type `View`
+- `Show()` - shows the popover anchored to a view you pass as a parameter
+- `Hide()` - hides the popover
+
+Use of the methods mentioned above:
+
+```csharp
+popover.Show(anchorView);
+popover.Hide();
+```
+
+Popover can be attached to a view using the `AttachedPopover` attached property. Such a popover can be displayed or hidden (dismissed) by calling the `ShowAttachedPopover()` and `HideAttachedPopover()` extension methods on the view:
+
+```csharp
+button.ShowAttachedPopover();
+button.HideAttachedPopover();
+```
+
+## SimpleToolkit.SimpleShell
+
+[](https://www.nuget.org/packages/SimpleToolkit.SimpleShell/)
+
+The *SimpleToolkit.SimpleShell* package provides you with a simplified implementation of .NET MAUI `Shell` that lets you easily create a custom navigation experience in your .NET MAUI applications.
+
+### Getting Started
+
+In order to use *SimpleToolkit.SimpleShell*, you need to call the `UseSimpleShell()` extension method in your `MauiProgram.cs` file:
+
+```csharp
+builder.UseSimpleShell();
+```
+
+### SimpleShell
+
+`SimpleShell` is a simplified implementation of .NET MAUI `Shell`. All `SimpleShell` is is just a simple container for your content with the ability to put the hosting area for pages wherever you want. Thanks to that, you are able to add custom tab bars, navigation bars, flyouts, etc. to your `Shell` application while using great `Shell` URI-based navigation.
+
+```xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+As you can see, the logical navigation structure is defined with `ShellContent`, `Tab`, etc. as in normal .NET MAUI `Shell`. However, visual structure has to be defined manually using the `Content` property. The hosting area for pages is represented by the `SimpleNavigationHost` view that can occur in the visual hierarchy **just once**.
+
+SimpleShell provides you with some bindable properties which simplify the creation of custom navigation controls:
+
+- `CurrentPage` - the currently selected `Page`
+- `CurrentShellSection` - the currently selected `ShellSection` (`Tab`)
+- `CurrentShellContent` - the currently selected `ShellContent`
+- `ShellSections` - read-only list of all `ShellSection`s in the shell
+- `ShellContents` - read-only list of all `ShellContent`s in the shell
+
+The code behind of the XAML sample above:
+
+```csharp
+private async void TabButtonClicked(object sender, EventArgs e)
+{
+ var button = sender as Button;
+ var shellItem = button.BindingContext as BaseShellItem;
+
+ // Navigate to a new tab if it is not the current tab
+ if (!CurrentState.Location.OriginalString.Contains(shellItem.Route))
+ await this.GoToAsync($"///{shellItem.Route}");
+}
+```
+
+Navigation between pages works exactly the same as in .NET MAUI `Shell`, just use the common `Shell.Current.GoToAsync()`. Pages that are not part of the shell hierarchy can be registered using the `Routing.RegisterRoute()` method.
+
+Output:
+
+
+
+
+
+ Android
+
+
+ iOS
+
+
+ Windows
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#### Visual states
+
+`SimpleShell` provides multiple groups of states.
+
+#### `ShellSection` states
+
+States in the `SimpleShellSectionState.[ShellSection route]` format:
+
+```xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+When a user navigates to a tab with a `HomeTab` route, the view named `tabBar` will have a red background, and when to a tab with a `SettingsTab` route, the view named `tabBar` will have a green background.
+
+#### `ShellContent` states
+
+States in the `SimpleShellContentState.[ShellContent route]` format:
+
+```xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+When a user navigates to a `ShellContent` with a `HomePage` route, the view named `tabBar` will have a yellow background, and when to a `ShellContent` with a `SettingsPage` route, the view named `tabBar` will have a blue background.
+
+#### Page type states
+
+States in the `SimplePageState.[Page type name]` format:
+
+```xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+When a user navigates to a `HomePage` page, the view named `tabBar` will have a purple background, and when to a `SettingsPage` page, the view named `tabBar` will have a orange background.
+
+#### Navigation stack states
+
+When a user navigates to a page that is part of the shell hierarchy, `SimpleShell` goes to the `RootPage` state, otherwise `SimpleShell` goes to the `RegisteredPage` state:
+
+```xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+#### Why not use `SimpleShell` and use .NET MAUI `Shell` instead
+
+- .NET MAUI `Shell` offers a platform-specific appearance.
+- Platform-specific navigation controls that .NET MAUI `Shell` provides probably have better performance than controls composed of multiple .NET MAUI views.
+- A `SimpleShell`-based application may not have as good accessibility in some scenarios due to the lack of platform-specific navigation controls. .NET MAUI `Shell` should be accessible out of the box since it uses platform-specific controls.
+- Maybe I have implemented something wrong that has a negative impact on the performance, accessibility, or something like that.
+
+#### Implementation details
+
+The `SimpleShell` class is inherited from the .NET MAUI `Shell` class, but all the handlers are implemented from the ground up. These handlers are inspired by the WinUI `Shell` handlers.
+
+`SimpleShell` currently does not provide any page transitions. Pages are simply swapped in a container during navigation.
+
+## SimpleToolkit.SimpleShell.Controls
+
+[](https://www.nuget.org/packages/SimpleToolkit.SimpleShell.Controls/)
+
+*SimpleToolkit.SimpleShell.Controls* is a collection of ready-to-use, navigation-related controls (not only) for `SimpleShell`.
+
+### Getting Started
+
+In order to use *SimpleToolkit.SimpleShell.Controls*, you need to call the `UseSimpleToolkit()` extension method in your `MauiProgram.cs` file:
+
+```csharp
+builder.UseSimpleToolkit();
+```
+
+
+
+
+
+
\ No newline at end of file
diff --git a/images/logo playground.svg b/images/logo playground.svg
new file mode 100644
index 0000000..3fea450
--- /dev/null
+++ b/images/logo playground.svg
@@ -0,0 +1,171 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/images/logo_empty_black.svg b/images/logo_empty_black.svg
new file mode 100644
index 0000000..4a1c6c5
--- /dev/null
+++ b/images/logo_empty_black.svg
@@ -0,0 +1,66 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/images/logo_filled_black.svg b/images/logo_filled_black.svg
new file mode 100644
index 0000000..7618e3c
--- /dev/null
+++ b/images/logo_filled_black.svg
@@ -0,0 +1,71 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/images/logo_with_background.png b/images/logo_with_background.png
new file mode 100644
index 0000000..dfab0fb
Binary files /dev/null and b/images/logo_with_background.png differ
diff --git a/images/logo_with_background.svg b/images/logo_with_background.svg
new file mode 100644
index 0000000..6951d11
--- /dev/null
+++ b/images/logo_with_background.svg
@@ -0,0 +1,99 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/images/readme/android_popover.gif b/images/readme/android_popover.gif
new file mode 100644
index 0000000..db60209
Binary files /dev/null and b/images/readme/android_popover.gif differ
diff --git a/images/readme/android_simpleshell.gif b/images/readme/android_simpleshell.gif
new file mode 100644
index 0000000..4a99aa7
Binary files /dev/null and b/images/readme/android_simpleshell.gif differ
diff --git a/images/readme/ios_popover.gif b/images/readme/ios_popover.gif
new file mode 100644
index 0000000..894da17
Binary files /dev/null and b/images/readme/ios_popover.gif differ
diff --git a/images/readme/ios_simpleshell.gif b/images/readme/ios_simpleshell.gif
new file mode 100644
index 0000000..1969c10
Binary files /dev/null and b/images/readme/ios_simpleshell.gif differ
diff --git a/images/readme/star_button.png b/images/readme/star_button.png
new file mode 100644
index 0000000..d5fa426
Binary files /dev/null and b/images/readme/star_button.png differ
diff --git a/images/readme/stars.png b/images/readme/stars.png
new file mode 100644
index 0000000..0748196
Binary files /dev/null and b/images/readme/stars.png differ
diff --git a/images/readme/windows_popover.gif b/images/readme/windows_popover.gif
new file mode 100644
index 0000000..8827b46
Binary files /dev/null and b/images/readme/windows_popover.gif differ
diff --git a/images/readme/windows_simpleshell.gif b/images/readme/windows_simpleshell.gif
new file mode 100644
index 0000000..5592dcd
Binary files /dev/null and b/images/readme/windows_simpleshell.gif differ
diff --git a/src/SimpleToolkit.Core/ContentButtonEventArgs.cs b/src/SimpleToolkit.Core/ContentButtonEventArgs.cs
index 3be530d..5a12fbd 100644
--- a/src/SimpleToolkit.Core/ContentButtonEventArgs.cs
+++ b/src/SimpleToolkit.Core/ContentButtonEventArgs.cs
@@ -1,7 +1,13 @@
namespace SimpleToolkit.Core
{
+ ///
+ /// Arguments of events.
+ ///
public class ContentButtonEventArgs : EventArgs
{
+ ///
+ /// Position of an interaction relative to the
+ ///
public Point InteractionPosition { get; init; }
}
}
diff --git a/src/SimpleToolkit.Core/Extensions/AppHostBuilderExtensions.cs b/src/SimpleToolkit.Core/Extensions/AppHostBuilderExtensions.cs
index f1c2ac0..3fd609c 100644
--- a/src/SimpleToolkit.Core/Extensions/AppHostBuilderExtensions.cs
+++ b/src/SimpleToolkit.Core/Extensions/AppHostBuilderExtensions.cs
@@ -4,6 +4,11 @@ namespace SimpleToolkit.Core
{
public static class AppHostBuilderExtensions
{
+ ///
+ /// Configures the SimpleToolkit.Core package.
+ ///
+ ///
+ ///
public static MauiAppBuilder UseSimpleToolkit(this MauiAppBuilder builder)
{
builder.ConfigureMauiHandlers(handlers =>
diff --git a/src/SimpleToolkit.Core/Extensions/PopoverExtensions.cs b/src/SimpleToolkit.Core/Extensions/PopoverExtensions.cs
index 4e3f228..6bb2f1c 100644
--- a/src/SimpleToolkit.Core/Extensions/PopoverExtensions.cs
+++ b/src/SimpleToolkit.Core/Extensions/PopoverExtensions.cs
@@ -1,13 +1,24 @@
namespace SimpleToolkit.Core
{
+ ///
+ /// Extension methods for Popover control.
+ ///
public static class PopoverExtensions
{
+ ///
+ /// Shows a popover that is attached to the view.
+ ///
+ /// The view to which the popover is attached.
public static void ShowAttachedPopover(this View parentView)
{
var popover = Popover.GetAttachedPopover(parentView);
popover.Show(parentView);
}
+ ///
+ /// Hides a popover that is attached to the view.
+ ///
+ /// The view to which the popover is attached.
public static void HideAttachedPopover(this View parentView)
{
var popover = Popover.GetAttachedPopover(parentView);
diff --git a/src/SimpleToolkit.Core/Handlers/ContentButton/ContentButtonHandler.Android.cs b/src/SimpleToolkit.Core/Handlers/ContentButton/ContentButtonHandler.Android.cs
index 7452134..9452508 100644
--- a/src/SimpleToolkit.Core/Handlers/ContentButton/ContentButtonHandler.Android.cs
+++ b/src/SimpleToolkit.Core/Handlers/ContentButton/ContentButtonHandler.Android.cs
@@ -2,10 +2,8 @@
using Android.Views;
using Android.Views.Accessibility;
-using Microsoft.Maui.Controls;
using Microsoft.Maui.Handlers;
using Microsoft.Maui.Platform;
-using static Android.Icu.Text.Transliterator;
using static Android.Views.View;
namespace SimpleToolkit.Core.Handlers
@@ -24,7 +22,6 @@ protected override ContentViewGroup CreatePlatformView()
platformView.Clickable = true;
var v = platformView.NextFocusDownId;
- //platformView.KeyPress += PlatformViewKeyPress;
platformView.Touch += PlatformViewTouch;
platformView.Click += PlatformViewClick;
@@ -94,33 +91,6 @@ bool IsTouchInViewTapRect()
}
}
- private void PlatformViewKeyPress(object sender, KeyEventArgs e)
- {
- if (sender is not Android.Views.View view)
- return;
-
- if (!IsRightKey(e.KeyCode))
- return;
-
- var position = new Point(view.Width / 2f, view.Height / 2f);
-
- switch (e.Event.Action)
- {
- case Android.Views.KeyEventActions.Down:
- virtualView.OnPressed(position);
- break;
- case Android.Views.KeyEventActions.Up:
- virtualView.OnReleased(position);
- virtualView.OnClicked();
- break;
- }
-
- bool IsRightKey(Android.Views.Keycode keycode)
- {
- return keycode == Android.Views.Keycode.Space || keycode == Android.Views.Keycode.Enter;
- }
- }
-
private class ButtonAccessibilityDelegate : AccessibilityDelegate
{
public override void OnInitializeAccessibilityNodeInfo(Android.Views.View host, AccessibilityNodeInfo info)
diff --git a/src/SimpleToolkit.Core/Handlers/ContentButton/ContentButtonHandler.Windows.cs b/src/SimpleToolkit.Core/Handlers/ContentButton/ContentButtonHandler.Windows.cs
index fdccb71..9a30df3 100644
--- a/src/SimpleToolkit.Core/Handlers/ContentButton/ContentButtonHandler.Windows.cs
+++ b/src/SimpleToolkit.Core/Handlers/ContentButton/ContentButtonHandler.Windows.cs
@@ -41,21 +41,17 @@ protected ContentButtonHandler(IPropertyMapper mapper, CommandMapper commandMapp
protected override SimpleContentPanel CreatePlatformView()
{
- if (VirtualView == null)
- {
- throw new InvalidOperationException($"{nameof(VirtualView)} must be set to create a LayoutView");
- }
+ _ = VirtualView ?? throw new InvalidOperationException($"{nameof(VirtualView)} must be set to create a SimpleContentPanel");
var view = new SimpleContentPanel
{
CrossPlatformMeasure = VirtualView.CrossPlatformMeasure,
- CrossPlatformArrange = VirtualView.CrossPlatformArrange
+ CrossPlatformArrange = VirtualView.CrossPlatformArrange,
+ IsTabStop = true,
+ UseSystemFocusVisuals = true,
+ FocusVisualMargin = new Microsoft.UI.Xaml.Thickness(-3)
};
- view.IsTabStop = true;
- view.UseSystemFocusVisuals = true;
- view.FocusVisualMargin = new Microsoft.UI.Xaml.Thickness(-3);
-
return view;
}
@@ -86,7 +82,7 @@ protected override void ConnectHandler(SimpleContentPanel platformView)
base.ConnectHandler(platformView);
}
- void OnPointerPressed(object sender, PointerRoutedEventArgs e)
+ private void OnPointerPressed(object sender, PointerRoutedEventArgs e)
{
var position = e.GetCurrentPoint(PlatformView).Position;
@@ -95,7 +91,7 @@ void OnPointerPressed(object sender, PointerRoutedEventArgs e)
VirtualView.OnPressed(new Point(position.X, position.Y));
}
- void OnPointerReleased(object sender, PointerRoutedEventArgs e)
+ private void OnPointerReleased(object sender, PointerRoutedEventArgs e)
{
var position = e.GetCurrentPoint(PlatformView).Position;
@@ -106,7 +102,7 @@ void OnPointerReleased(object sender, PointerRoutedEventArgs e)
alreadyReleased = true;
}
- void OnPointerExited(object sender, PointerRoutedEventArgs e)
+ private void OnPointerExited(object sender, PointerRoutedEventArgs e)
{
var position = e.GetCurrentPoint(PlatformView).Position;
@@ -125,9 +121,9 @@ private void OnKeyDown(object sender, KeyRoutedEventArgs e)
alreadyReleased = false;
VirtualView.OnPressed(new Point(position.X, position.Y));
- VirtualView.OnClicked();
if (!alreadyReleased)
VirtualView.OnReleased(new Point(position.X, position.Y));
+ VirtualView.OnClicked();
alreadyReleased = true;
}
diff --git a/src/SimpleToolkit.Core/Handlers/ContentButton/ContentButtonHandler.iOS.cs b/src/SimpleToolkit.Core/Handlers/ContentButton/ContentButtonHandler.iOS.cs
index 0ae1190..5e5d682 100644
--- a/src/SimpleToolkit.Core/Handlers/ContentButton/ContentButtonHandler.iOS.cs
+++ b/src/SimpleToolkit.Core/Handlers/ContentButton/ContentButtonHandler.iOS.cs
@@ -1,7 +1,6 @@
#if IOS || MACCATALYST
using Foundation;
-using JavaScriptCore;
using Microsoft.Maui.Handlers;
using UIKit;
@@ -17,20 +16,40 @@ protected override Microsoft.Maui.Platform.ContentView CreatePlatformView()
platformView.AccessibilityTraits = UIAccessibilityTrait.Button;
- platformView.AddGestureRecognizer(new UICustomGestureRecognizer(g =>
+ //platformView.AddGestureRecognizer(new UICustomGestureRecognizer(g =>
+ //{
+ // var location = g.LocationInView(g.View);
+
+ // switch (g.State)
+ // {
+ // case UIGestureRecognizerState.Began:
+ // virtualView.OnPressed(new Point(location.X, location.Y));
+ // break;
+ // case UIGestureRecognizerState.Ended:
+ // virtualView.OnReleased(new Point(location.X, location.Y));
+ // virtualView.OnClicked();
+ // break;
+ // case UIGestureRecognizerState.Failed:
+ // virtualView.OnReleased(new Point(location.X, location.Y));
+ // break;
+ // }
+ //}));
+
+ platformView.AddGestureRecognizer(new UITapGestureRecognizer(g =>
{
var location = g.LocationInView(g.View);
+ System.Diagnostics.Debug.WriteLine("👋");
+
switch (g.State)
{
- case UIGestureRecognizerState.Began:
- virtualView.OnPressed(new Point(location.X, location.Y));
- break;
case UIGestureRecognizerState.Ended:
+ virtualView.OnPressed(new Point(location.X, location.Y));
virtualView.OnReleased(new Point(location.X, location.Y));
virtualView.OnClicked();
break;
case UIGestureRecognizerState.Failed:
+ virtualView.OnPressed(new Point(location.X, location.Y));
virtualView.OnReleased(new Point(location.X, location.Y));
break;
}
@@ -39,7 +58,8 @@ protected override Microsoft.Maui.Platform.ContentView CreatePlatformView()
return platformView;
}
- protected class UICustomGestureRecognizer : UIGestureRecognizer
+ // TODO: Find out why my gesture recognizer conflicts with scrolling in ScrollView
+ protected class UICustomGestureRecognizer : UITapGestureRecognizer
{
private Action action;
@@ -64,6 +84,22 @@ public override void TouchesEnded(NSSet touches, UIEvent evt)
State = UIGestureRecognizerState.Ended;
action?.Invoke(this);
+
+ State = UIGestureRecognizerState.Possible;
+ }
+
+ public override void TouchesMoved(NSSet touches, UIEvent evt)
+ {
+ base.TouchesMoved(touches, evt);
+
+ UITouch touch = touches.AnyObject as UITouch;
+
+ if (touch is not null && !View.Frame.Contains(touch.LocationInView(View)))
+ {
+ State = UIGestureRecognizerState.Cancelled;
+ }
+
+ action?.Invoke(this);
}
public override void TouchesCancelled(NSSet touches, UIEvent evt)
diff --git a/src/SimpleToolkit.Core/Handlers/Icon/IconHandler.Android.cs b/src/SimpleToolkit.Core/Handlers/Icon/IconHandler.Android.cs
index e5de48a..7496c5b 100644
--- a/src/SimpleToolkit.Core/Handlers/Icon/IconHandler.Android.cs
+++ b/src/SimpleToolkit.Core/Handlers/Icon/IconHandler.Android.cs
@@ -22,9 +22,14 @@ public partial class IconHandler : ViewHandler
{
};
- ImageSourcePartLoader _imageSourcePartLoader;
+ ImageSourcePartLoader imageSourcePartLoader;
public ImageSourcePartLoader SourceLoader =>
- _imageSourcePartLoader ??= new ImageSourcePartLoader(this, () => VirtualView, OnSetImageSource);
+ imageSourcePartLoader ??= new ImageSourcePartLoader(this, () => VirtualView, OnSetImageSource);
+
+ public override bool NeedsContainer =>
+ VirtualView?.Background != null ||
+ base.NeedsContainer;
+
public IconHandler() : base(Mapper)
{
@@ -34,6 +39,7 @@ public IconHandler(IPropertyMapper mapper) : base(mapper ?? Mapper)
{
}
+
protected override ImageView CreatePlatformView()
{
var imageView = new AppCompatImageView(Context);
@@ -74,11 +80,7 @@ public override void PlatformArrange(Microsoft.Maui.Graphics.Rect frame)
base.PlatformArrange(frame);
}
- public override bool NeedsContainer =>
- VirtualView?.Background != null ||
- base.NeedsContainer;
-
- void OnSetImageSource(Drawable obj) =>
+ private void OnSetImageSource(Drawable obj) =>
PlatformView.SetImageDrawable(obj);
private void ApplyTint(Color color)
@@ -88,16 +90,14 @@ private void ApplyTint(Color color)
PlatformView.SetColorFilter(color.ToPlatform(), PorterDuff.Mode.SrcIn ?? throw new InvalidOperationException("PorterDuff.Mode.SrcIn should not be null at runtime"));
}
- public static void MapSource(IconHandler handler, Icon image) =>
- MapSourceAsync(handler, image).FireAndForget(handler);
+ public static void MapSource(IconHandler handler, Icon icon) =>
+ MapSourceAsync(handler, icon).FireAndForget(handler);
- public static Task MapSourceAsync(IconHandler handler, Icon image) =>
+ public static Task MapSourceAsync(IconHandler handler, Icon icon) =>
handler.SourceLoader.UpdateImageSourceAsync();
- public static void MapTintColor(IconHandler handler, Icon image)
- {
- handler.ApplyTint(image.TintColor);
- }
+ public static void MapTintColor(IconHandler handler, Icon icon) =>
+ handler.ApplyTint(icon.TintColor);
}
}
diff --git a/src/SimpleToolkit.Core/Handlers/Icon/IconHandler.Windows.cs b/src/SimpleToolkit.Core/Handlers/Icon/IconHandler.Windows.cs
index c46a439..05db1e8 100644
--- a/src/SimpleToolkit.Core/Handlers/Icon/IconHandler.Windows.cs
+++ b/src/SimpleToolkit.Core/Handlers/Icon/IconHandler.Windows.cs
@@ -84,7 +84,11 @@ public static Task MapSourceAsync(IconHandler handler, Icon icon)
else if (iconSource is FontIconSource fontIconSource)
{
handler.fontIcon.FontFamily = fontIconSource.FontFamily;
- handler.fontIcon.FontSize = handler.fontSize = fontIconSource.FontSize;
+ handler.fontSize = fontIconSource.FontSize;
+ if (icon.Height is not -1 && icon.Width is not -1)
+ handler.fontIcon.FontSize = Math.Min(fontIconSource.FontSize, Math.Min(icon.Height, icon.Width));
+ else
+ handler.fontIcon.FontSize = fontIconSource.FontSize;
handler.fontIcon.FontStyle = fontIconSource.FontStyle;
handler.fontIcon.FontWeight = fontIconSource.FontWeight;
handler.fontIcon.Glyph = fontIconSource.Glyph;
diff --git a/src/SimpleToolkit.Core/Handlers/Icon/IconHandler.iOS.cs b/src/SimpleToolkit.Core/Handlers/Icon/IconHandler.iOS.cs
index 2def2f7..daaa602 100644
--- a/src/SimpleToolkit.Core/Handlers/Icon/IconHandler.iOS.cs
+++ b/src/SimpleToolkit.Core/Handlers/Icon/IconHandler.iOS.cs
@@ -18,9 +18,14 @@ public class IconHandler : ViewHandler
{
};
- ImageSourcePartLoader _imageSourcePartLoader;
+ ImageSourcePartLoader imageSourcePartLoader;
public ImageSourcePartLoader SourceLoader =>
- _imageSourcePartLoader ??= new ImageSourcePartLoader(this, () => VirtualView, OnSetImageSource);
+ imageSourcePartLoader ??= new ImageSourcePartLoader(this, () => VirtualView, OnSetImageSource);
+
+ public override bool NeedsContainer =>
+ VirtualView?.Background != null ||
+ base.NeedsContainer;
+
public IconHandler() : base(Mapper)
{
@@ -30,6 +35,7 @@ public IconHandler(IPropertyMapper mapper) : base(mapper ?? Mapper)
{
}
+
protected override UIImageView CreatePlatformView()
{
var imageView = new MauiImageView();
@@ -58,15 +64,10 @@ protected override void DisconnectHandler(UIImageView platformView)
SourceLoader.Reset();
}
- public override bool NeedsContainer =>
- VirtualView?.Background != null ||
- base.NeedsContainer;
-
void OnSetImageSource(UIImage obj)
{
PlatformView.Image = obj.ImageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate);
- if (VirtualView is Icon bitmapIcon)
- PlatformView.TintColor = bitmapIcon.TintColor.ToPlatform();
+ PlatformView.TintColor = VirtualView.TintColor.ToPlatform();
}
private void ApplyTint(Color color)
@@ -89,19 +90,14 @@ void OnWindowChanged(object sender, EventArgs e)
UpdateValue(nameof(Icon.Source));
}
- public static void MapSource(IconHandler handler, Icon image) =>
- MapSourceAsync(handler, image).FireAndForget(handler);
+ public static void MapSource(IconHandler handler, Icon icon) =>
+ MapSourceAsync(handler, icon).FireAndForget(handler);
- public static Task MapSourceAsync(IconHandler handler, Icon image) =>
+ public static Task MapSourceAsync(IconHandler handler, Icon icon) =>
handler.SourceLoader.UpdateImageSourceAsync();
- public static void MapTintColor(IconHandler handler, Icon image)
- {
- if (image is Icon bitmapIcon)
- {
- handler.ApplyTint(bitmapIcon.TintColor);
- }
- }
+ public static void MapTintColor(IconHandler handler, Icon icon) =>
+ handler.ApplyTint(icon.TintColor);
}
}
diff --git a/src/SimpleToolkit.Core/Handlers/Platform/UIPopoverViewController.cs b/src/SimpleToolkit.Core/Handlers/Platform/PopoverViewController.cs
similarity index 95%
rename from src/SimpleToolkit.Core/Handlers/Platform/UIPopoverViewController.cs
rename to src/SimpleToolkit.Core/Handlers/Platform/PopoverViewController.cs
index 6e97fb1..4dbdad6 100644
--- a/src/SimpleToolkit.Core/Handlers/Platform/UIPopoverViewController.cs
+++ b/src/SimpleToolkit.Core/Handlers/Platform/PopoverViewController.cs
@@ -12,15 +12,15 @@
namespace SimpleToolkit.Core.Handlers
{
- public class UIPopoverViewController : UIViewController
+ public class PopoverViewController : UIViewController
{
- readonly IMauiContext mauiContext;
+ private readonly IMauiContext mauiContext;
- public IPopover VirtualView { get; private set; }
internal UIViewController ViewController { get; private set; }
+ public IPopover VirtualView { get; private set; }
- public UIPopoverViewController(IMauiContext mauiContext)
+ public PopoverViewController(IMauiContext mauiContext)
{
this.mauiContext = mauiContext ?? throw new ArgumentNullException(nameof(mauiContext));
}
@@ -28,6 +28,7 @@ public UIPopoverViewController(IMauiContext mauiContext)
public override void ViewDidAppear(bool animated)
{
+ // Remove all the default styling of the popover container
View.Superview.Layer.CornerRadius = 0f;
View.Superview.Layer.BackgroundColor = Colors.Transparent.ToCGColor();
View.Superview.Layer.ShadowColor = null;
@@ -44,7 +45,7 @@ public override void ViewDidLayoutSubviews()
if (VirtualView.Content is null)
return;
- var measure = (VirtualView.Content as IView).Measure(double.PositiveInfinity, double.PositiveInfinity); // These two are different
+ var measure = (VirtualView.Content as IView).Measure(double.PositiveInfinity, double.PositiveInfinity);
PreferredContentSize = new CGSize(measure.Width, measure.Height);
foreach (var subview in View.Subviews)
@@ -129,7 +130,7 @@ private void UpdateContainerGrid(IPopover virtualView)
if (contentView?.Children.Any() == true)
contentView.Children.Clear();
- // I do not understand how sizing on iOS works. This is only hopefully working solution I came up with
+ // I do not understand how sizing on iOS works. This is the only hopefully working solution I came up with
contentView = new Microsoft.Maui.Controls.Grid
{
HorizontalOptions = LayoutOptions.Start,
@@ -180,6 +181,7 @@ public override UIModalPresentationStyle GetAdaptivePresentationStyle(UIPresenta
UIModalPresentationStyle.None;
}
+ // Helps to remove default styling of the popover container
private class PopoverBackgroundView : UIPopoverBackgroundView
{
[Export("arrowHeight")]
diff --git a/src/SimpleToolkit.Core/Handlers/Platform/SimpleContentPanel.cs b/src/SimpleToolkit.Core/Handlers/Platform/SimpleContentPanel.cs
index 7139cff..10b7c0c 100644
--- a/src/SimpleToolkit.Core/Handlers/Platform/SimpleContentPanel.cs
+++ b/src/SimpleToolkit.Core/Handlers/Platform/SimpleContentPanel.cs
@@ -12,14 +12,15 @@ namespace SimpleToolkit.Core.Handlers
{
public class SimpleContentPanel : Panel
{
- readonly Path borderPath;
- IShape borderShape;
+ private readonly Path borderPath;
+ private IShape borderShape;
internal Path BorderPath => borderPath;
internal Func CrossPlatformMeasure { get; set; }
internal Func CrossPlatformArrange { get; set; }
internal Action Clicked { get; set; }
+
public SimpleContentPanel()
{
borderPath = new Path();
@@ -29,6 +30,24 @@ public SimpleContentPanel()
}
+ public void UpdateBackground(Paint background)
+ {
+ if (borderPath == null)
+ return;
+
+ borderPath.UpdateBackground(background);
+ }
+
+ public void UpdateBorderShape(IShape borderShape)
+ {
+ this.borderShape = borderShape;
+
+ if (borderPath == null)
+ return;
+
+ borderPath.UpdateBorderShape(this.borderShape, ActualWidth, ActualHeight);
+ }
+
protected override AutomationPeer OnCreateAutomationPeer()
{
return new ContentButtonAutomationPeer(this);
@@ -92,23 +111,6 @@ internal void EnsureBorderPath()
}
}
- public void UpdateBackground(Paint background)
- {
- if (borderPath == null)
- return;
-
- borderPath.UpdateBackground(background);
- }
-
- public void UpdateBorderShape(IShape borderShape)
- {
- this.borderShape = borderShape;
-
- if (borderPath == null)
- return;
-
- borderPath.UpdateBorderShape(this.borderShape, ActualWidth, ActualHeight);
- }
private class ContentButtonAutomationPeer : FrameworkElementAutomationPeer, IInvokeProvider
{
diff --git a/src/SimpleToolkit.Core/Handlers/Platform/SimpleFlyout.cs b/src/SimpleToolkit.Core/Handlers/Platform/SimpleFlyout.cs
index 83ab95f..16b5999 100644
--- a/src/SimpleToolkit.Core/Handlers/Platform/SimpleFlyout.cs
+++ b/src/SimpleToolkit.Core/Handlers/Platform/SimpleFlyout.cs
@@ -12,20 +12,20 @@ namespace SimpleToolkit.Core.Handlers
{
public class SimpleFlyout : Flyout
{
- readonly IMauiContext mauiContext;
+ private readonly IMauiContext mauiContext;
+ private Action panelCleanUp;
+ private Func createControl;
+ internal Panel Control { get; set; }
+ internal XamlStyle FlyoutStyle { get; private set; } = new(typeof(FlyoutPresenter));
+ public IPopover VirtualView { get; private set; }
+
+
public SimpleFlyout(IMauiContext mauiContext)
{
this.mauiContext = mauiContext ?? throw new ArgumentNullException(nameof(mauiContext));
}
- public IPopover VirtualView { get; private set; }
-
- internal Panel Control { get; set; }
- internal XamlStyle FlyoutStyle { get; private set; } = new(typeof(FlyoutPresenter));
-
- Action panelCleanUp;
- Func createControl;
public void SetElement(IPopover element)
{
diff --git a/src/SimpleToolkit.Core/Handlers/Platform/SimplePopupWindow.cs b/src/SimpleToolkit.Core/Handlers/Platform/SimplePopupWindow.cs
index 5c8dc95..c77bff1 100644
--- a/src/SimpleToolkit.Core/Handlers/Platform/SimplePopupWindow.cs
+++ b/src/SimpleToolkit.Core/Handlers/Platform/SimplePopupWindow.cs
@@ -11,7 +11,7 @@ namespace SimpleToolkit.Core.Handlers
{
public class SimplePopupWindow : PopupWindow
{
- readonly IMauiContext mauiContext;
+ private readonly IMauiContext mauiContext;
public IPopover VirtualView { get; private set; }
@@ -46,14 +46,11 @@ public void Show(IElement anchor)
return;
}
- var content = VirtualView.Content.ToPlatform(mauiContext);
-
- // Height and Width have to be set to not show the PopupWindow outside of screen bounds
-
var measure = (VirtualView.Content as IView).Measure(double.PositiveInfinity, double.PositiveInfinity);
var width = (int)Math.Round(measure.Width * DeviceDisplay.Current.MainDisplayInfo.Density);
var height = (int)Math.Round(measure.Height * DeviceDisplay.Current.MainDisplayInfo.Density);
+ //var content = VirtualView.Content.ToPlatform(mauiContext);
//content.Measure(ViewGroup.LayoutParams.WrapContent, ViewGroup.LayoutParams.WrapContent);
//content.Post(() =>
@@ -61,6 +58,7 @@ public void Show(IElement anchor)
// VirtualView.Content.Layout(new Rect(0, 0, width, height));
//});
+ // Height and Width have to be set to not show the PopupWindow outside of screen bounds
if (width != 0 || height != 0)
{
Width = width;
diff --git a/src/SimpleToolkit.Core/Handlers/Platform/WrapperPanel.cs b/src/SimpleToolkit.Core/Handlers/Platform/WrapperPanel.cs
index 4ecd72d..1105036 100644
--- a/src/SimpleToolkit.Core/Handlers/Platform/WrapperPanel.cs
+++ b/src/SimpleToolkit.Core/Handlers/Platform/WrapperPanel.cs
@@ -11,8 +11,11 @@ namespace SimpleToolkit.Core.Handlers
{
internal class WrapperPanel : Panel
{
- readonly View view;
-
+ private readonly View view;
+ private readonly FrameworkElement frameworkElement;
+ private IPlatformViewHandler handler => view.Handler as IPlatformViewHandler;
+
+
public WrapperPanel(View view, IMauiContext mauiContext)
{
ArgumentNullException.ThrowIfNull(view);
@@ -21,25 +24,21 @@ public WrapperPanel(View view, IMauiContext mauiContext)
this.view = view;
this.view.MeasureInvalidated += OnMeasureInvalidated;
- FrameworkElement = view.ToPlatform(mauiContext);
- Children.Add(FrameworkElement);
+ frameworkElement = view.ToPlatform(mauiContext);
+ Children.Add(frameworkElement);
// make sure we re-measure once the template is applied
- FrameworkElement.Loaded += (sender, args) =>
+ frameworkElement.Loaded += (sender, args) =>
{
// If the view is a layout (stacklayout, grid, etc) we need to trigger a layout pass
// with all the controls in a consistent native state (i.e., loaded) so they'll actually
// have Bounds set
- Handler?.PlatformView?.InvalidateMeasure(View);
+ handler?.PlatformView?.InvalidateMeasure(view);
InvalidateMeasure();
};
}
- IView View => view;
- IPlatformViewHandler? Handler => View.Handler as IPlatformViewHandler;
-
- FrameworkElement FrameworkElement { get; }
public void CleanUp()
{
@@ -49,7 +48,7 @@ public void CleanUp()
protected override global::Windows.Foundation.Size ArrangeOverride(global::Windows.Foundation.Size finalSize)
{
view.Frame = new Rect(0, 0, finalSize.Width, finalSize.Height);
- FrameworkElement?.Arrange(new WRect(0, 0, finalSize.Width, finalSize.Height));
+ frameworkElement?.Arrange(new WRect(0, 0, finalSize.Width, finalSize.Height));
if (view.Width <= 0 || view.Height <= 0)
{
@@ -67,9 +66,9 @@ public void CleanUp()
protected override global::Windows.Foundation.Size MeasureOverride(global::Windows.Foundation.Size availableSize)
{
- FrameworkElement.Measure(availableSize);
+ frameworkElement.Measure(availableSize);
- var request = FrameworkElement.DesiredSize;
+ var request = frameworkElement.DesiredSize;
if (request.Height < 0)
{
diff --git a/src/SimpleToolkit.Core/Handlers/Popover/PopoverHandler.Android.cs b/src/SimpleToolkit.Core/Handlers/Popover/PopoverHandler.Android.cs
index f2c4dd8..f67eb62 100644
--- a/src/SimpleToolkit.Core/Handlers/Popover/PopoverHandler.Android.cs
+++ b/src/SimpleToolkit.Core/Handlers/Popover/PopoverHandler.Android.cs
@@ -29,10 +29,10 @@ public static void MapContent(PopoverHandler handler, IPopover popover)
public static void MapShow(PopoverHandler handler, IPopover popover, object parentView)
{
- if (parentView is IElement anchor)
- {
- handler.PlatformView.Show(anchor);
- }
+ if (parentView is not IElement anchor)
+ return;
+
+ handler.PlatformView.Show(anchor);
}
public static void MapHide(PopoverHandler handler, IPopover popover, object arg3)
diff --git a/src/SimpleToolkit.Core/Handlers/Popover/PopoverHandler.Shared.cs b/src/SimpleToolkit.Core/Handlers/Popover/PopoverHandler.Shared.cs
index 1561a50..4d21262 100644
--- a/src/SimpleToolkit.Core/Handlers/Popover/PopoverHandler.Shared.cs
+++ b/src/SimpleToolkit.Core/Handlers/Popover/PopoverHandler.Shared.cs
@@ -13,6 +13,7 @@ public partial class PopoverHandler
[nameof(IPopover.Hide)] = MapHide,
};
+
public PopoverHandler(IPropertyMapper mapper, CommandMapper commandMapper)
: base(mapper ?? Mapper, commandMapper ?? CommandMapper)
{
@@ -23,25 +24,4 @@ public PopoverHandler()
{
}
}
-
-#if !(WINDOWS || ANDROID || IOS || MACCATALYST)
-
- public partial class PopoverHandler : Microsoft.Maui.Handlers.ElementHandler
- {
- protected override object CreatePlatformElement() => throw new NotSupportedException();
-
- public static void MapContent(PopoverHandler handler, IPopover popover)
- {
- }
-
- public static void MapHide(PopoverHandler handler, IPopover popover, object arg3)
- {
- }
-
- public static void MapShow(PopoverHandler handler, IPopover popover, object parentView)
- {
- }
- }
-
-#endif
}
\ No newline at end of file
diff --git a/src/SimpleToolkit.Core/Handlers/Popover/PopoverHandler.Standard.cs b/src/SimpleToolkit.Core/Handlers/Popover/PopoverHandler.Standard.cs
new file mode 100644
index 0000000..4b2c8bd
--- /dev/null
+++ b/src/SimpleToolkit.Core/Handlers/Popover/PopoverHandler.Standard.cs
@@ -0,0 +1,23 @@
+#if !(WINDOWS || ANDROID || IOS || MACCATALYST)
+
+namespace SimpleToolkit.Core.Handlers
+{
+ public partial class PopoverHandler : Microsoft.Maui.Handlers.ElementHandler
+ {
+ protected override object CreatePlatformElement() => throw new NotSupportedException();
+
+ public static void MapContent(PopoverHandler handler, IPopover popover)
+ {
+ }
+
+ public static void MapHide(PopoverHandler handler, IPopover popover, object arg3)
+ {
+ }
+
+ public static void MapShow(PopoverHandler handler, IPopover popover, object parentView)
+ {
+ }
+ }
+}
+
+#endif
\ No newline at end of file
diff --git a/src/SimpleToolkit.Core/Handlers/Popover/PopoverHandler.Windows.cs b/src/SimpleToolkit.Core/Handlers/Popover/PopoverHandler.Windows.cs
index 671527c..4df31ed 100644
--- a/src/SimpleToolkit.Core/Handlers/Popover/PopoverHandler.Windows.cs
+++ b/src/SimpleToolkit.Core/Handlers/Popover/PopoverHandler.Windows.cs
@@ -31,10 +31,10 @@ public static void MapContent(PopoverHandler handler, IPopover popover)
public static void MapShow(PopoverHandler handler, IPopover popover, object parentView)
{
- if (parentView is IElement anchor)
- {
- handler.PlatformView.Show(anchor);
- }
+ if (parentView is not IElement anchor)
+ return;
+
+ handler.PlatformView.Show(anchor);
}
public static void MapHide(PopoverHandler handler, IPopover popover, object arg3)
diff --git a/src/SimpleToolkit.Core/Handlers/Popover/PopoverHandler.iOS.cs b/src/SimpleToolkit.Core/Handlers/Popover/PopoverHandler.iOS.cs
index e937121..23159a4 100644
--- a/src/SimpleToolkit.Core/Handlers/Popover/PopoverHandler.iOS.cs
+++ b/src/SimpleToolkit.Core/Handlers/Popover/PopoverHandler.iOS.cs
@@ -6,20 +6,20 @@
namespace SimpleToolkit.Core.Handlers
{
- public partial class PopoverHandler : ElementHandler
+ public partial class PopoverHandler : ElementHandler
{
- protected override UIPopoverViewController CreatePlatformElement()
+ protected override PopoverViewController CreatePlatformElement()
{
- return new UIPopoverViewController(MauiContext);
+ return new PopoverViewController(MauiContext);
}
- protected override void ConnectHandler(UIPopoverViewController platformView)
+ protected override void ConnectHandler(PopoverViewController platformView)
{
base.ConnectHandler(platformView);
platformView.SetElement(VirtualView);
}
- protected override void DisconnectHandler(UIPopoverViewController platformView)
+ protected override void DisconnectHandler(PopoverViewController platformView)
{
base.DisconnectHandler(platformView);
platformView.CleanUp();
diff --git a/src/SimpleToolkit.Core/SimpleToolkit.Core.csproj b/src/SimpleToolkit.Core/SimpleToolkit.Core.csproj
index 507a515..732b701 100644
--- a/src/SimpleToolkit.Core/SimpleToolkit.Core.csproj
+++ b/src/SimpleToolkit.Core/SimpleToolkit.Core.csproj
@@ -1,4 +1,4 @@
-
+
net6.0;net6.0-android;net6.0-ios;net6.0-maccatalyst
@@ -15,13 +15,41 @@
10.0.17763.0
10.0.17763.0
6.5
+
+ SimpleToolkit.Core
+ SimpleToolkit.Core
+ LICENSE
+ MAUI, Controls, Button, Popover, Icon
+ RadekVyM
+ ..\..\packages
+ 1.0.0
+ -preview1
+ $(VersionPrefix)$(VersionSuffix)
+ Collection of simple .NET MAUI controls and helpers that is part of SimpleToolkit library.
+ https://github.com/RadekVyM/SimpleToolkit
+ https://github.com/RadekVyM/SimpleToolkit
+ git
+ logo_with_background.png
+ Copyright © RadekVyM and contributors
+
+
+
+ True
+ \
+
+
+ True
+ \
+
+
+
\ No newline at end of file
diff --git a/src/SimpleToolkit.Core/Views/ContentButton/ContentButton.cs b/src/SimpleToolkit.Core/Views/ContentButton/ContentButton.cs
index b5e2172..5beffea 100644
--- a/src/SimpleToolkit.Core/Views/ContentButton/ContentButton.cs
+++ b/src/SimpleToolkit.Core/Views/ContentButton/ContentButton.cs
@@ -1,10 +1,22 @@
namespace SimpleToolkit.Core
{
+ ///
+ /// Button that can hold whatever content you want.
+ ///
[ContentProperty(nameof(Content))]
public class ContentButton : ContentView, IContentButton
{
+ ///
+ /// Event that fires when the button is clicked.
+ ///
public event EventHandler Clicked;
+ ///
+ /// Event that fires when the button is pressed.
+ ///
public event EventHandler Pressed;
+ ///
+ /// Event that fires when the button is released.
+ ///
public event EventHandler Released;
public virtual void OnClicked()
diff --git a/src/SimpleToolkit.Core/Views/ContentButton/IContentButton.cs b/src/SimpleToolkit.Core/Views/ContentButton/IContentButton.cs
index 1516ae8..d6f40fc 100644
--- a/src/SimpleToolkit.Core/Views/ContentButton/IContentButton.cs
+++ b/src/SimpleToolkit.Core/Views/ContentButton/IContentButton.cs
@@ -1,9 +1,21 @@
namespace SimpleToolkit.Core
{
+ ///
+ /// Button that can hold whatever content you want.
+ ///
public interface IContentButton : IContentView
{
+ ///
+ /// Method that is called when the button is clicked.
+ ///
void OnClicked();
+ ///
+ /// Method that is called when the button is pressed.
+ ///
void OnPressed(Point pressPosition);
+ ///
+ /// Method that is called when the button is released.
+ ///
void OnReleased(Point releasePosition);
}
}
diff --git a/src/SimpleToolkit.Core/Views/Icon/IIcon.cs b/src/SimpleToolkit.Core/Views/Icon/IIcon.cs
index 0d9b5eb..66dae47 100644
--- a/src/SimpleToolkit.Core/Views/Icon/IIcon.cs
+++ b/src/SimpleToolkit.Core/Views/Icon/IIcon.cs
@@ -2,8 +2,14 @@
namespace SimpleToolkit.Core
{
+ ///
+ /// Control displaying a tinted image.
+ ///
public interface IIcon : IImage
{
+ ///
+ /// Tint color of an image.
+ ///
Color TintColor { get; set; }
}
}
diff --git a/src/SimpleToolkit.Core/Views/Icon/Icon.cs b/src/SimpleToolkit.Core/Views/Icon/Icon.cs
index cc2d44c..68266f6 100644
--- a/src/SimpleToolkit.Core/Views/Icon/Icon.cs
+++ b/src/SimpleToolkit.Core/Views/Icon/Icon.cs
@@ -1,5 +1,8 @@
namespace SimpleToolkit.Core
{
+ ///
+ /// Control displaying a tinted image.
+ ///
public class Icon : Image, IIcon
{
public static readonly BindableProperty TintColorProperty = BindableProperty.Create(nameof(TintColor), typeof(Color), typeof(Icon), defaultValue: Colors.Black);
diff --git a/src/SimpleToolkit.Core/Views/Popover/IPopover.cs b/src/SimpleToolkit.Core/Views/Popover/IPopover.cs
index 5fce97f..5a3d039 100644
--- a/src/SimpleToolkit.Core/Views/Popover/IPopover.cs
+++ b/src/SimpleToolkit.Core/Views/Popover/IPopover.cs
@@ -1,10 +1,22 @@
namespace SimpleToolkit.Core
{
+ ///
+ /// Popover that can be anchored to a view.
+ ///
public interface IPopover : IElement
{
+ ///
+ /// Content of the popover
+ ///
View Content { get; set; }
-
+ ///
+ /// Shows the popover anchored to the view.
+ ///
+ /// The view to which the popover is anchored.
void Show(View parentView);
+ ///
+ /// Hides the popover.
+ ///
void Hide();
}
}
diff --git a/src/SimpleToolkit.Core/Views/Popover/Popover.cs b/src/SimpleToolkit.Core/Views/Popover/Popover.cs
index 983534c..007bff8 100644
--- a/src/SimpleToolkit.Core/Views/Popover/Popover.cs
+++ b/src/SimpleToolkit.Core/Views/Popover/Popover.cs
@@ -4,6 +4,9 @@
namespace SimpleToolkit.Core
{
+ ///
+ /// Popover that can be anchored to a view.
+ ///
[ContentProperty(nameof(Content))]
public class Popover : Element, IPopover
{
@@ -18,16 +21,25 @@ public virtual View Content
set => SetValue(ContentProperty, value);
}
+ ///
+ /// Returns a popover that is attached to the view.
+ ///
+ /// The view to which the popover is attached.
+ /// The popover that is attached to the view.
public static Popover GetAttachedPopover(BindableObject view)
{
_ = view ?? throw new ArgumentNullException(nameof(view));
return (Popover)view.GetValue(AttachedPopoverProperty);
}
+ ///
+ /// Attaches the popover to the view.
+ ///
+ /// The view to which the popover will be attached.
+ /// The popover that will be attached to the view.
public static void SetAttachedPopover(BindableObject view, Popover popover)
{
_ = view ?? throw new ArgumentNullException(nameof(view));
- _ = popover ?? throw new ArgumentNullException(nameof(popover));
view.SetValue(AttachedPopoverProperty, popover);
}
diff --git a/src/SimpleToolkit.Playground/MauiProgram.cs b/src/SimpleToolkit.Playground/MauiProgram.cs
index 078e40d..a5371ad 100644
--- a/src/SimpleToolkit.Playground/MauiProgram.cs
+++ b/src/SimpleToolkit.Playground/MauiProgram.cs
@@ -15,6 +15,7 @@ public static MauiApp CreateMauiApp()
{
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
+ fonts.AddFont("Font-Awesome-Solid.otf", "FontAwesomeSolid");
});
builder.UseSimpleToolkit();
diff --git a/src/SimpleToolkit.Playground/Resources/Fonts/Font-Awesome-Solid.otf b/src/SimpleToolkit.Playground/Resources/Fonts/Font-Awesome-Solid.otf
new file mode 100644
index 0000000..71e7c02
Binary files /dev/null and b/src/SimpleToolkit.Playground/Resources/Fonts/Font-Awesome-Solid.otf differ
diff --git a/src/SimpleToolkit.Playground/Resources/Images/arrow_left.svg b/src/SimpleToolkit.Playground/Resources/Images/arrow_left.svg
new file mode 100644
index 0000000..ae96b81
--- /dev/null
+++ b/src/SimpleToolkit.Playground/Resources/Images/arrow_left.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/SimpleToolkit.Playground/SimpleAppShell.xaml b/src/SimpleToolkit.Playground/SimpleAppShell.xaml
index dd91a1a..a9acc7d 100644
--- a/src/SimpleToolkit.Playground/SimpleAppShell.xaml
+++ b/src/SimpleToolkit.Playground/SimpleAppShell.xaml
@@ -46,36 +46,16 @@
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -140,7 +120,7 @@
-
+
@@ -151,29 +131,67 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ controls:SimpleShellIcon.SelectedIcon="flame_filled.png">
+ controls:SimpleShellIcon.SelectedIcon="https://www.itnetwork.cz/images/63461/mobile/apps_icon.png">
@@ -184,109 +202,113 @@
+ controls:SimpleShellIcon.SelectedIcon="case_filled.png">
+ controls:SimpleShellIcon.SelectedIcon="avatar_filled.png">
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ VerticalOptions="Center">
-
-
-
+
+
+
+
+
+
+
+ VerticalOptions="Center">
-
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
@@ -300,7 +322,7 @@
SelectedItem="{Binding Source={x:Reference thisShell}, Path=CurrentShellContent}"
ItemsAlignment="Center"
IsScrollable="False"
- ItemSelected="TabView_ItemSelected"
+ ItemSelected="TabBarItemSelected"
Style="{StaticResource MaterialTabbar}"/>
@@ -308,4 +330,56 @@
+
+
\ No newline at end of file
diff --git a/src/SimpleToolkit.Playground/SimpleAppShell.xaml.cs b/src/SimpleToolkit.Playground/SimpleAppShell.xaml.cs
index bebe0e9..5c7fb75 100644
--- a/src/SimpleToolkit.Playground/SimpleAppShell.xaml.cs
+++ b/src/SimpleToolkit.Playground/SimpleAppShell.xaml.cs
@@ -18,23 +18,23 @@ public SimpleAppShell()
InitializeComponent();
designLanguagesListPopover.Items = new List
- {
- new DesignLanguageItem("Material3", () =>
- {
- VisualStateManager.GoToState(this, "Material3");
- designButton.HideAttachedPopover();
- }),
- new DesignLanguageItem("Cupertino", () =>
{
- VisualStateManager.GoToState(this, "Cupertino");
- designButton.HideAttachedPopover();
- }),
- new DesignLanguageItem("Fluent", () =>
- {
- VisualStateManager.GoToState(this, "Fluent");
- designButton.HideAttachedPopover();
- }),
- };
+ new DesignLanguageItem("Material3", () =>
+ {
+ VisualStateManager.GoToState(this, "Material3");
+ designButton.HideAttachedPopover();
+ }),
+ new DesignLanguageItem("Cupertino", () =>
+ {
+ VisualStateManager.GoToState(this, "Cupertino");
+ designButton.HideAttachedPopover();
+ }),
+ new DesignLanguageItem("Fluent", () =>
+ {
+ VisualStateManager.GoToState(this, "Fluent");
+ designButton.HideAttachedPopover();
+ }),
+ };
VisualStateManager.GoToState(this, "Material3");
@@ -44,7 +44,7 @@ public SimpleAppShell()
Routing.RegisterRoute(nameof(FirstGreenDetailPage), typeof(FirstGreenDetailPage));
}
- private async void Button_Clicked(object sender, EventArgs e)
+ private async void ShellItemButtonClicked(object sender, EventArgs e)
{
var button = sender as Button;
var shellItem = button.BindingContext as BaseShellItem;
@@ -53,7 +53,7 @@ private async void Button_Clicked(object sender, EventArgs e)
await this.GoToAsync($"///{shellItem.Route}");
}
- private async void TabView_ItemSelected(object sender, TabItemSelectedEventArgs e)
+ private async void TabBarItemSelected(object sender, TabItemSelectedEventArgs e)
{
if (!CurrentState.Location.OriginalString.Contains(e.ShellItem.Route))
await this.GoToAsync($"///{e.ShellItem.Route}");
@@ -66,7 +66,7 @@ private async void BackButtonClicked(object sender, EventArgs e)
private bool orangeAdded = false;
- private void Button_Clicked_1(object sender, EventArgs e)
+ private void AddButtonClicked(object sender, EventArgs e)
{
if (!orangeAdded)
{
@@ -76,6 +76,8 @@ private void Button_Clicked_1(object sender, EventArgs e)
Route = nameof(OrangePage),
ContentTemplate = new DataTemplate(typeof(OrangePage))
});
+
+ addButton.IsVisible = false;
}
orangeAdded = true;
@@ -83,7 +85,7 @@ private void Button_Clicked_1(object sender, EventArgs e)
private void ShowPopoverButtonClicked(object sender, EventArgs e)
{
- var button = sender as Button;
+ var button = sender as View;
button.ShowAttachedPopover();
}
diff --git a/src/SimpleToolkit.Playground/SimpleToolkit.Playground.csproj b/src/SimpleToolkit.Playground/SimpleToolkit.Playground.csproj
index c6a5cff..0aa37b1 100644
--- a/src/SimpleToolkit.Playground/SimpleToolkit.Playground.csproj
+++ b/src/SimpleToolkit.Playground/SimpleToolkit.Playground.csproj
@@ -49,6 +49,8 @@
+
+
@@ -64,7 +66,12 @@
-
+
+
+
+
+
+
@@ -85,15 +92,24 @@
MSBuild:Compile
+
+ MSBuild:Compile
+
MSBuild:Compile
MSBuild:Compile
+
+ MSBuild:Compile
+
MSBuild:Compile
+
+ MSBuild:Compile
+
MSBuild:Compile
diff --git a/src/SimpleToolkit.Playground/Views/Pages/ContentButtonPage.xaml b/src/SimpleToolkit.Playground/Views/Pages/ContentButtonPage.xaml
new file mode 100644
index 0000000..e1967b9
--- /dev/null
+++ b/src/SimpleToolkit.Playground/Views/Pages/ContentButtonPage.xaml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/SimpleToolkit.Playground/Views/Pages/ContentButtonPage.xaml.cs b/src/SimpleToolkit.Playground/Views/Pages/ContentButtonPage.xaml.cs
new file mode 100644
index 0000000..1e01f80
--- /dev/null
+++ b/src/SimpleToolkit.Playground/Views/Pages/ContentButtonPage.xaml.cs
@@ -0,0 +1,15 @@
+namespace SimpleToolkit.SimpleShell.Playground.Views.Pages
+{
+ public partial class ContentButtonPage : ContentPage
+ {
+ public ContentButtonPage()
+ {
+ InitializeComponent();
+ }
+
+ private void StarButtonClicked(object sender, EventArgs e)
+ {
+ Shell.Current.GoToAsync(nameof(FirstGreenDetailPage));
+ }
+ }
+}
diff --git a/src/SimpleToolkit.Playground/Views/Pages/Green/FirstGreenDetailPage.xaml b/src/SimpleToolkit.Playground/Views/Pages/Green/FirstGreenDetailPage.xaml
index e61232b..b7286b8 100644
--- a/src/SimpleToolkit.Playground/Views/Pages/Green/FirstGreenDetailPage.xaml
+++ b/src/SimpleToolkit.Playground/Views/Pages/Green/FirstGreenDetailPage.xaml
@@ -3,7 +3,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="SimpleToolkit.SimpleShell.Playground.Views.Pages.FirstGreenDetailPage"
Title="FirstGreenDetailPage">
-
+
+
+
\ No newline at end of file
diff --git a/src/SimpleToolkit.Playground/Views/Pages/IconPage.xaml b/src/SimpleToolkit.Playground/Views/Pages/IconPage.xaml
new file mode 100644
index 0000000..5d55fde
--- /dev/null
+++ b/src/SimpleToolkit.Playground/Views/Pages/IconPage.xaml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/SimpleToolkit.Playground/Views/Pages/IconPage.xaml.cs b/src/SimpleToolkit.Playground/Views/Pages/IconPage.xaml.cs
new file mode 100644
index 0000000..cf1cd6e
--- /dev/null
+++ b/src/SimpleToolkit.Playground/Views/Pages/IconPage.xaml.cs
@@ -0,0 +1,10 @@
+namespace SimpleToolkit.SimpleShell.Playground.Views.Pages
+{
+ public partial class IconPage : ContentPage
+ {
+ public IconPage()
+ {
+ InitializeComponent();
+ }
+ }
+}
diff --git a/src/SimpleToolkit.Playground/Views/Pages/PopoverPage.xaml b/src/SimpleToolkit.Playground/Views/Pages/PopoverPage.xaml
new file mode 100644
index 0000000..5a405c1
--- /dev/null
+++ b/src/SimpleToolkit.Playground/Views/Pages/PopoverPage.xaml
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/SimpleToolkit.Playground/Views/Pages/PopoverPage.xaml.cs b/src/SimpleToolkit.Playground/Views/Pages/PopoverPage.xaml.cs
new file mode 100644
index 0000000..d74d939
--- /dev/null
+++ b/src/SimpleToolkit.Playground/Views/Pages/PopoverPage.xaml.cs
@@ -0,0 +1,19 @@
+using SimpleToolkit.Core;
+
+namespace SimpleToolkit.SimpleShell.Playground.Views.Pages
+{
+ public partial class PopoverPage : ContentPage
+ {
+ public PopoverPage()
+ {
+ InitializeComponent();
+ }
+
+ private void ButtonClicked(object sender, EventArgs e)
+ {
+ var button = sender as Button;
+
+ button.ShowAttachedPopover();
+ }
+ }
+}
diff --git a/src/SimpleToolkit.SimpleShell.Controls/AttachedProperties.cs b/src/SimpleToolkit.SimpleShell.Controls/AttachedProperties.cs
index fd32f78..5e62b7b 100644
--- a/src/SimpleToolkit.SimpleShell.Controls/AttachedProperties.cs
+++ b/src/SimpleToolkit.SimpleShell.Controls/AttachedProperties.cs
@@ -1,18 +1,30 @@
namespace SimpleToolkit.SimpleShell.Controls
{
- public static class SimpleIcon
+ public static class SimpleShellIcon
{
public static readonly BindableProperty SelectedIconProperty =
BindableProperty.CreateAttached("SelectedIcon", typeof(ImageSource), typeof(BaseShellItem), null);
- public static ImageSource GetSelectedIcon(BindableObject view)
+ ///
+ /// Returns an of an image that should be displayed when the item is selected.
+ ///
+ /// The item to which the is attached.
+ /// The that is attached to the item.
+ public static ImageSource GetSelectedIcon(BindableObject item)
{
- return (ImageSource)view.GetValue(SelectedIconProperty);
+ _ = item ?? throw new ArgumentNullException(nameof(item));
+ return (ImageSource)item.GetValue(SelectedIconProperty);
}
- public static void SetSelectedIcon(BindableObject view, ImageSource value)
+ ///
+ /// Attaches to the item an of an image that should be displayed when the item is selected.
+ ///
+ /// The item to which the will be attached.
+ /// The of an image that will be attached to the item.
+ public static void SetSelectedIcon(BindableObject item, ImageSource value)
{
- view.SetValue(SelectedIconProperty, value);
+ _ = item ?? throw new ArgumentNullException(nameof(item));
+ item.SetValue(SelectedIconProperty, value);
}
}
}
diff --git a/src/SimpleToolkit.SimpleShell.Controls/DesignLanguage.cs b/src/SimpleToolkit.SimpleShell.Controls/DesignLanguage.cs
index 84de18d..97da670 100644
--- a/src/SimpleToolkit.SimpleShell.Controls/DesignLanguage.cs
+++ b/src/SimpleToolkit.SimpleShell.Controls/DesignLanguage.cs
@@ -1,5 +1,8 @@
namespace SimpleToolkit.SimpleShell.Controls
{
+ ///
+ /// Enumeration of supported design languages
+ ///
public enum DesignLanguage
{
Material3, Cupertino, Fluent
diff --git a/src/SimpleToolkit.SimpleShell.Controls/Extensions/ColorExtensions.cs b/src/SimpleToolkit.SimpleShell.Controls/Extensions/ColorExtensions.cs
index 9098f86..e55c734 100644
--- a/src/SimpleToolkit.SimpleShell.Controls/Extensions/ColorExtensions.cs
+++ b/src/SimpleToolkit.SimpleShell.Controls/Extensions/ColorExtensions.cs
@@ -6,7 +6,7 @@ public static Brush OffsetBrushColorValue(this Brush brush, float valueOffset)
{
if (brush is SolidColorBrush solidColorBrush)
{
- return new SolidColorBrush(solidColorBrush.Color.OffsetColorValue(valueOffset));
+ return new SolidColorBrush(solidColorBrush.Color?.OffsetColorValue(valueOffset));
}
else if (brush is LinearGradientBrush linearGradientBrush)
{
@@ -26,7 +26,7 @@ public static GradientStopCollection OffsetStopsCollectionColorValue(this Gradie
foreach (var stop in stops)
{
- stops.Add(new GradientStop(stop.Color.OffsetColorValue(valueOffset), stop.Offset));
+ stops.Add(new GradientStop(stop.Color?.OffsetColorValue(valueOffset), stop.Offset));
}
return newStops;
diff --git a/src/SimpleToolkit.SimpleShell.Controls/ListPopoverItemClickedEventArgs.cs b/src/SimpleToolkit.SimpleShell.Controls/ListPopoverItemClickedEventArgs.cs
index 908a411..f76b6e5 100644
--- a/src/SimpleToolkit.SimpleShell.Controls/ListPopoverItemClickedEventArgs.cs
+++ b/src/SimpleToolkit.SimpleShell.Controls/ListPopoverItemClickedEventArgs.cs
@@ -2,8 +2,14 @@
{
public delegate void ListPopoverItemSelectedEventHandler(object sender, ListPopoverItemSelectedEventArgs e);
+ ///
+ /// Arguments of selection event.
+ ///
public class ListPopoverItemSelectedEventArgs : EventArgs
{
+ ///
+ /// The selected item.
+ ///
public object Item { get; internal set; }
}
}
\ No newline at end of file
diff --git a/src/SimpleToolkit.SimpleShell.Controls/SimpleToolkit - Backup.SimpleShell.Controls.csproj b/src/SimpleToolkit.SimpleShell.Controls/SimpleToolkit - Backup.SimpleShell.Controls.csproj
new file mode 100644
index 0000000..bdfeef9
--- /dev/null
+++ b/src/SimpleToolkit.SimpleShell.Controls/SimpleToolkit - Backup.SimpleShell.Controls.csproj
@@ -0,0 +1,62 @@
+
+
+
+ net6.0;net6.0-android;net6.0-ios;net6.0-maccatalyst
+ $(TargetFrameworks);net6.0-windows10.0.19041.0
+
+
+ true
+ true
+ enable
+
+ 14.2
+ 14.0
+ 21.0
+ 10.0.17763.0
+ 10.0.17763.0
+ 6.5
+
+ SimpleToolkit.SimpleShell.Controls
+ SimpleToolkit.SimpleShell.Controls
+ LICENSE
+ MAUI, Controls, Shell, Navigation
+ RadekVyM
+ ..\..\packages
+ 1.0.0
+ Collection of ready-to-use, navigation-related controls that is part of SimpleToolkit library. These controls work well with SimpleShell.
+ https://github.com/RadekVyM/SimpleToolkit
+ https://github.com/RadekVyM/SimpleToolkit
+ git
+ logo_with_background.png
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ True
+ \
+
+
+ True
+ \
+
+
+
+
diff --git a/src/SimpleToolkit.SimpleShell.Controls/SimpleToolkit.SimpleShell.Controls.csproj b/src/SimpleToolkit.SimpleShell.Controls/SimpleToolkit.SimpleShell.Controls.csproj
index 4786023..7b7e29f 100644
--- a/src/SimpleToolkit.SimpleShell.Controls/SimpleToolkit.SimpleShell.Controls.csproj
+++ b/src/SimpleToolkit.SimpleShell.Controls/SimpleToolkit.SimpleShell.Controls.csproj
@@ -15,20 +15,51 @@
10.0.17763.0
10.0.17763.0
6.5
+
+ SimpleToolkit.SimpleShell.Controls
+ SimpleToolkit.SimpleShell.Controls
+ LICENSE
+ MAUI, Controls, Shell, Navigation
+ RadekVyM
+ ..\..\packages
+ 1.0.0
+ -preview1
+ $(VersionPrefix)$(VersionSuffix)
+ Collection of ready-to-use, navigation-related controls that is part of SimpleToolkit library. These controls work well with SimpleShell.
+ https://github.com/RadekVyM/SimpleToolkit
+ https://github.com/RadekVyM/SimpleToolkit
+ git
+ logo_with_background.png
+ Copyright © RadekVyM and contributors
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+ True
+ \
+
+
+ True
+ \
+
diff --git a/src/SimpleToolkit.SimpleShell.Controls/TabItemSelectedEventArgs.cs b/src/SimpleToolkit.SimpleShell.Controls/TabItemSelectedEventArgs.cs
index 8da9c00..915491a 100644
--- a/src/SimpleToolkit.SimpleShell.Controls/TabItemSelectedEventArgs.cs
+++ b/src/SimpleToolkit.SimpleShell.Controls/TabItemSelectedEventArgs.cs
@@ -2,8 +2,14 @@
{
public delegate void TabItemSelectedEventHandler(object sender, TabItemSelectedEventArgs e);
+ ///
+ /// Arguments of a tab selection event.
+ ///
public class TabItemSelectedEventArgs : EventArgs
{
+ ///
+ /// The selected item.
+ ///
public BaseShellItem ShellItem { get; internal set; }
}
}
diff --git a/src/SimpleToolkit.SimpleShell.Controls/Views/ListPopover/IListPopover.cs b/src/SimpleToolkit.SimpleShell.Controls/Views/ListPopover/IListPopover.cs
new file mode 100644
index 0000000..3bf31d4
--- /dev/null
+++ b/src/SimpleToolkit.SimpleShell.Controls/Views/ListPopover/IListPopover.cs
@@ -0,0 +1,27 @@
+using SimpleToolkit.Core;
+
+namespace SimpleToolkit.SimpleShell.Controls
+{
+ ///
+ /// Popover containing a list of items that is styled according to the selected .
+ ///
+ public interface IListPopover : IPopover
+ {
+ IEnumerable Items { get; set; }
+ DesignLanguage DesignLanguage { get; set; }
+ Brush Background { get; set; }
+ Color IconColor { get; set; }
+ Color IconSelectionColor { get; set; }
+ double MaximumWidthRequest { get; set; }
+ double MinimumWidthRequest { get; set; }
+ object SelectedItem { get; set; }
+ Brush SelectionBrush { get; set; }
+ Color TextColor { get; set; }
+ Color TextSelectionColor { get; set; }
+
+ ///
+ /// Event that fires when an item is selected.
+ ///
+ event ListPopoverItemSelectedEventHandler ItemSelected;
+ }
+}
\ No newline at end of file
diff --git a/src/SimpleToolkit.SimpleShell.Controls/Views/ListPopover/ListPopover.Shared.cs b/src/SimpleToolkit.SimpleShell.Controls/Views/ListPopover/ListPopover.Shared.cs
index 8094b87..710b209 100644
--- a/src/SimpleToolkit.SimpleShell.Controls/Views/ListPopover/ListPopover.Shared.cs
+++ b/src/SimpleToolkit.SimpleShell.Controls/Views/ListPopover/ListPopover.Shared.cs
@@ -3,10 +3,11 @@
namespace SimpleToolkit.SimpleShell.Controls
{
- // TODO: A11y
-
+ ///
+ /// containing a list of items that is styled according to the selected .
+ ///
[ContentProperty(nameof(Items))]
- public partial class ListPopover : Popover
+ public partial class ListPopover : Popover, IListPopover
{
private Border rootBorder;
private Grid rootGrid;
@@ -168,8 +169,6 @@ private void SetUpBaseStructure()
{
VerticalOptions = LayoutOptions.Start,
HorizontalOptions = LayoutOptions.Start,
- StrokeThickness = 0,
- Stroke = Colors.Transparent,
Background = Background,
Shadow = null,
StrokeShape = new RoundRectangle
@@ -260,7 +259,7 @@ private ContentButton CreateButton(ListItem item)
Style = new Style(typeof(ContentButton)),
BindingContext = item,
};
-
+ // TODO: Try to remove this one Grid
var grid = new Grid
{
ColumnDefinitions = new ColumnDefinitionCollection(
@@ -270,7 +269,6 @@ private ContentButton CreateButton(ListItem item)
Style = new Style(typeof(Grid)),
BindingContext = item,
};
-
var innerGrid = new Grid
{
ColumnDefinitions = new ColumnDefinitionCollection(
@@ -281,7 +279,6 @@ private ContentButton CreateButton(ListItem item)
Style = new Style(typeof(Grid)),
BindingContext = item,
};
-
var label = new Label
{
Text = item.Title,
@@ -316,7 +313,9 @@ private ContentButton CreateButton(ListItem item)
button.Content = grid;
- //CompressedLayout.SetIsHeadless(grid, true);
+ SemanticProperties.SetDescription(button, item.Title);
+
+ CompressedLayout.SetIsHeadless(grid, true);
CompressedLayout.SetIsHeadless(innerGrid, true);
return button;
@@ -490,6 +489,8 @@ private void ItemPropertyChanged(object sender, System.ComponentModel.PropertyCh
label.Text = titleIcon.Title;
image.Source = titleIcon.Icon;
+
+ SemanticProperties.SetDescription(item, titleIcon.Title);
}
UpdateIconsVisibility(listItems);
@@ -574,7 +575,7 @@ private static void OnTextColorChanged(BindableObject bindable, object oldValue,
var grid = item.Content as Grid;
var innerGrid = grid.Children[0] as Grid;
var label = innerGrid.Children[1] as Label;
-
+
if (newValue is not null)
label.TextColor = newValue as Color;
}
@@ -625,7 +626,10 @@ private static void OnTextSelectionColorChanged(BindableObject bindable, object
private static void OnBackgroundChanged(BindableObject bindable, object oldValue, object newValue)
{
var listPopover = bindable as ListPopover;
- listPopover.rootBorder.Background = newValue as Brush;
+ var newBrush = newValue as Brush;
+
+ listPopover.rootBorder.Stroke = newBrush.OffsetBrushColorValue(-0.1f);
+ listPopover.rootBorder.Background = newBrush;
listPopover.InvalidateGraphicsView();
}
diff --git a/src/SimpleToolkit.SimpleShell.Controls/Views/TabBar/ITabBar.cs b/src/SimpleToolkit.SimpleShell.Controls/Views/TabBar/ITabBar.cs
new file mode 100644
index 0000000..968c1e2
--- /dev/null
+++ b/src/SimpleToolkit.SimpleShell.Controls/Views/TabBar/ITabBar.cs
@@ -0,0 +1,35 @@
+namespace SimpleToolkit.SimpleShell.Controls
+{
+ ///
+ /// Tab bar that is styled according to the selected .
+ ///
+ public interface ITabBar
+ {
+ IEnumerable Items { get; set; }
+ IReadOnlyList HiddenItems { get; }
+ BaseShellItem SelectedItem { get; set; }
+ DesignLanguage DesignLanguage { get; set; }
+ Color TextColor { get; set; }
+ Color TextSelectionColor { get; set; }
+ Color IconColor { get; set; }
+ Color IconSelectionColor { get; set; }
+ Brush PrimaryBrush { get; set; }
+ string MoreTitle { get; set; }
+ ImageSource MoreIcon { get; set; }
+ double ItemWidthRequest { get; set; }
+ bool IsScrollable { get; set; }
+ LayoutAlignment ItemsAlignment { get; set; }
+ bool ShowButtonWhenMoreItemsDoNotFit { get; set; }
+ bool ShowMenuOnMoreButtonClick { get; set; }
+
+ ///
+ /// Event that fires when an item is selected.
+ ///
+ event TabItemSelectedEventHandler ItemSelected;
+
+ ///
+ /// Event that fires when the "More" button is clicked.
+ ///
+ event EventHandler MoreButtonClicked;
+ }
+}
\ No newline at end of file
diff --git a/src/SimpleToolkit.SimpleShell.Controls/Views/TabBar/TabBar.Fluent.cs b/src/SimpleToolkit.SimpleShell.Controls/Views/TabBar/TabBar.Fluent.cs
index 77a4832..b290001 100644
--- a/src/SimpleToolkit.SimpleShell.Controls/Views/TabBar/TabBar.Fluent.cs
+++ b/src/SimpleToolkit.SimpleShell.Controls/Views/TabBar/TabBar.Fluent.cs
@@ -46,6 +46,8 @@ private void UpdateDrawableToFluent()
drawable.IsSelectedHiddenItem = isMoreButtonShown && selectedIndex == stackLayout.Count - 1;
drawable.IconSize = iconSize;
drawable.IconMargin = iconMargin;
+ drawable.AnimationProgressDone = 0;
+ drawable.AnimationProgressRest = 0;
}
private async Task AnimateFluentToSelected()
@@ -73,13 +75,20 @@ private async Task AnimateFluentToSelected()
if (toPosition < stackLayout.Count - 1)
drawable.IsSelectedHiddenItem = false;
+ var needsToBeTraveled = toPosition - fromPosition;
+ drawable.AnimationDirection = needsToBeTraveled > 0;
+ needsToBeTraveled = Math.Abs(needsToBeTraveled);
+
var animation = new Animation(v =>
{
drawable.SelectedItemRelativePosition = v;
- drawable.AnimationProgress = Math.Abs((toPosition - fromPosition) / v);
+ drawable.AnimationProgressDone = Math.Abs(v - fromPosition);
+ drawable.AnimationProgressRest = needsToBeTraveled - drawable.AnimationProgressDone;
+
graphicsView.Invalidate();
}, fromPosition, toPosition);
+ graphicsView.AbortAnimation("FluentLineAnimation");
animation.Commit(graphicsView, "FluentLineAnimation", length: animationLength, easing: Easing.SinInOut);
await Task.Delay((int)animationLength);
@@ -92,7 +101,9 @@ private class FluentDrawable : IDrawable, IDisposable
private float lineThickness = 4f;
private float defaultLineWidth = 16f;
- public double AnimationProgress { get; set; }
+ public bool AnimationDirection { get; set; } // left == false
+ public double AnimationProgressDone { get; set; }
+ public double AnimationProgressRest { get; set; }
public Color IconColor { get; set; }
public Brush LineBrush { get; set; }
public IList Views { get; set; }
@@ -157,6 +168,8 @@ public void Draw(ICanvas canvas, RectF dirtyRect)
canvas.RestoreState();
}
+ RectF lastLineRect;
+
private void DrawLine(ICanvas canvas, RectF dirtyRect, float leftPadding)
{
double leftItemsWidth = 0;
@@ -177,9 +190,11 @@ private void DrawLine(ICanvas canvas, RectF dirtyRect, float leftPadding)
var selectedView = Views[flooredPosition] as View;
var itemWidth = selectedView.Width;
- var left = (float)(leftItemsWidth + ((itemWidth - defaultLineWidth) / 2) - ScrollPosition + leftPadding + ((SelectedItemRelativePosition - flooredPosition) * itemWidth));
+ var defaultLeft = (float)(leftItemsWidth + ((itemWidth - defaultLineWidth) / 2) - ScrollPosition + leftPadding);
+ var left = (float)(defaultLeft + ((SelectedItemRelativePosition - flooredPosition) * itemWidth));
+ var width = defaultLineWidth;
- var lineRect = new RectF(left, dirtyRect.Height - bottomPadding - lineThickness, defaultLineWidth, lineThickness);
+ var lineRect = lastLineRect = new RectF(left, dirtyRect.Height - bottomPadding - lineThickness, width, lineThickness);
canvas.SetFillPaint(LineBrush ?? Colors.Black, lineRect);
diff --git a/src/SimpleToolkit.SimpleShell.Controls/Views/TabBar/TabBar.Shared.cs b/src/SimpleToolkit.SimpleShell.Controls/Views/TabBar/TabBar.Shared.cs
index 7289ee0..352ef80 100644
--- a/src/SimpleToolkit.SimpleShell.Controls/Views/TabBar/TabBar.Shared.cs
+++ b/src/SimpleToolkit.SimpleShell.Controls/Views/TabBar/TabBar.Shared.cs
@@ -2,9 +2,10 @@
namespace SimpleToolkit.SimpleShell.Controls
{
- // TODO: A11y
-
- public partial class TabBar : ContentView, IView
+ ///
+ /// Tab bar that is styled according to the selected .
+ ///
+ public partial class TabBar : ContentView, IView, ITabBar
{
private HorizontalStackLayout stackLayout;
private Grid rootGrid;
@@ -224,11 +225,8 @@ private int GetSelectedItemIndex()
return i;
}
- // TODO: Update selection of more button - if hidden item is selected, show more button as selected
private bool IsSelected(BindableObject bindableObject)
{
- // (bindableObject == moreButton && hiddenItems.Any(h => h.BindingContext == SelectedItem))
-
return bindableObject.BindingContext == SelectedItem || bindableObject == SelectedItem;
}
@@ -388,6 +386,8 @@ private ContentButton CreateButton(BaseShellItem item)
button.Content = grid;
+ SemanticProperties.SetDescription(button, item.Title);
+
CompressedLayout.SetIsHeadless(stackLayout, true);
CompressedLayout.SetIsHeadless(grid, true);
@@ -518,7 +518,7 @@ private void UpdateButton(ContentButton button)
if (IsSelected(shellItem))
{
- var selectedIcon = SimpleIcon.GetSelectedIcon(shellItem);
+ var selectedIcon = SimpleShellIcon.GetSelectedIcon(shellItem);
if (selectedIcon is not null && image.Source != selectedIcon)
image.Source = selectedIcon;
}
@@ -837,7 +837,7 @@ private void ShellItemPropertyChanged(object sender, System.ComponentModel.Prope
{
if (e.PropertyName != BaseShellItem.TitleProperty.PropertyName && e.PropertyName != BaseShellItem.IconProperty.PropertyName)
return;
-
+
if (stackLayout is null)
return;
@@ -854,6 +854,8 @@ private void ShellItemPropertyChanged(object sender, System.ComponentModel.Prope
image.Source = shellItem.Icon;
image.TintColor = IsSelected(item) ? IconSelectionColor : IconColor;
+
+ SemanticProperties.SetDescription(item, shellItem.Title);
}
}
diff --git a/src/SimpleToolkit.SimpleShell/Extensions/AppHostBuilderExtensions.cs b/src/SimpleToolkit.SimpleShell/Extensions/AppHostBuilderExtensions.cs
index 99faa2a..e3b6514 100644
--- a/src/SimpleToolkit.SimpleShell/Extensions/AppHostBuilderExtensions.cs
+++ b/src/SimpleToolkit.SimpleShell/Extensions/AppHostBuilderExtensions.cs
@@ -4,6 +4,11 @@ namespace SimpleToolkit.SimpleShell
{
public static class AppHostBuilderExtensions
{
+ ///
+ /// Configures the SimpleToolkit.SimpleShell package.
+ ///
+ ///
+ ///
public static MauiAppBuilder UseSimpleShell(this MauiAppBuilder builder)
{
builder.ConfigureMauiHandlers(handlers =>
diff --git a/src/SimpleToolkit.SimpleShell/Extensions/Extensions.cs b/src/SimpleToolkit.SimpleShell/Extensions/Extensions.cs
index 623268c..a39a573 100644
--- a/src/SimpleToolkit.SimpleShell/Extensions/Extensions.cs
+++ b/src/SimpleToolkit.SimpleShell/Extensions/Extensions.cs
@@ -1,6 +1,6 @@
-namespace SimpleToolkit.SimpleShell
+namespace SimpleToolkit.SimpleShell.Extensions
{
- internal static class Extensions
+ internal static class ElementExtensions
{
public static SimpleNavigationHost FindSimpleNavigationHost(this IView view)
{
diff --git a/src/SimpleToolkit.SimpleShell/Extensions/RoutingExtensions.cs b/src/SimpleToolkit.SimpleShell/Extensions/RoutingExtensions.cs
index ac5fd06..afd5684 100644
--- a/src/SimpleToolkit.SimpleShell/Extensions/RoutingExtensions.cs
+++ b/src/SimpleToolkit.SimpleShell/Extensions/RoutingExtensions.cs
@@ -2,9 +2,8 @@
{
internal static class RoutingExtensions
{
- const string ImplicitPrefix = "IMPL_";
- const string DefaultPrefix = "D_FAULT_";
- internal const string PathSeparator = "/";
+ private const string ImplicitPrefix = "IMPL_";
+ private const string DefaultPrefix = "D_FAULT_";
public static bool IsImplicit(BindableObject source)
{
diff --git a/src/SimpleToolkit.SimpleShell/Extensions/SimpleShellExtensions.cs b/src/SimpleToolkit.SimpleShell/Extensions/SimpleShellExtensions.cs
new file mode 100644
index 0000000..0ac9553
--- /dev/null
+++ b/src/SimpleToolkit.SimpleShell/Extensions/SimpleShellExtensions.cs
@@ -0,0 +1,52 @@
+namespace SimpleToolkit.SimpleShell.Extensions
+{
+ internal static class SimpleShellExtensions
+ {
+ public static IEnumerable GetShellSections(this BaseShellItem baseShellItem)
+ {
+ var list = new HashSet();
+
+ if (baseShellItem is ShellSection shellSection)
+ {
+ list.Add(shellSection);
+ }
+ else if (baseShellItem is ShellItem shellItem)
+ {
+ foreach (var item in shellItem.Items)
+ {
+ var shellSections = GetShellSections(item);
+ foreach (var section in shellSections)
+ list.Add(section);
+ }
+ }
+
+ return list;
+ }
+
+ public static IEnumerable GetShellContents(this BaseShellItem baseShellItem)
+ {
+ var list = new HashSet();
+
+ if (baseShellItem is ShellContent shellContent)
+ {
+ list.Add(shellContent);
+ }
+ else if (baseShellItem is ShellItem shellItem)
+ {
+ foreach (var item in shellItem.Items)
+ {
+ var shellContents = GetShellContents(item);
+ foreach (var content in shellContents)
+ list.Add(content);
+ }
+ }
+ else if (baseShellItem is ShellSection shellSection)
+ {
+ foreach (var content in shellSection.Items)
+ list.Add(content);
+ }
+
+ return list;
+ }
+ }
+}
diff --git a/src/SimpleToolkit.SimpleShell/Handlers/NavigationHost/SimpleNavigationHostHandler.Android.cs b/src/SimpleToolkit.SimpleShell/Handlers/NavigationHost/SimpleNavigationHostHandler.Android.cs
index e369b17..bd36984 100644
--- a/src/SimpleToolkit.SimpleShell/Handlers/NavigationHost/SimpleNavigationHostHandler.Android.cs
+++ b/src/SimpleToolkit.SimpleShell/Handlers/NavigationHost/SimpleNavigationHostHandler.Android.cs
@@ -16,6 +16,9 @@ public partial class SimpleNavigationHostHandler : ViewHandler
+ {
+ public SimpleNavigationHostHandler(IPropertyMapper mapper, CommandMapper commandMapper)
+ : base(mapper, commandMapper)
+ {
+ }
+
+ protected override System.Object CreatePlatformElement()
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
+
+#endif
\ No newline at end of file
diff --git a/src/SimpleToolkit.SimpleShell/Handlers/NavigationHost/SimpleNavigationHostHandler.Windows.cs b/src/SimpleToolkit.SimpleShell/Handlers/NavigationHost/SimpleNavigationHostHandler.Windows.cs
index 87c993d..455da46 100644
--- a/src/SimpleToolkit.SimpleShell/Handlers/NavigationHost/SimpleNavigationHostHandler.Windows.cs
+++ b/src/SimpleToolkit.SimpleShell/Handlers/NavigationHost/SimpleNavigationHostHandler.Windows.cs
@@ -1,13 +1,11 @@
-
+#if WINDOWS
+
using Microsoft.Maui.Handlers;
-#if WINDOWS
using WBorder = Microsoft.UI.Xaml.Controls.Border;
using WFrameworkElement = Microsoft.UI.Xaml.FrameworkElement;
-#endif
namespace SimpleToolkit.SimpleShell.Handlers
{
-#if WINDOWS
public partial class SimpleNavigationHostHandler : ViewHandler
{
public static IPropertyMapper Mapper = new PropertyMapper(ViewHandler.ViewMapper)
@@ -18,6 +16,9 @@ public partial class SimpleNavigationHostHandler : ViewHandler
- {
- public SimpleNavigationHostHandler(IPropertyMapper mapper, CommandMapper commandMapper)
- : base(mapper, commandMapper)
- {
- }
-
- protected override System.Object CreatePlatformElement()
- {
- throw new NotImplementedException();
- }
- }
-#endif
-}
\ No newline at end of file
+#endif
\ No newline at end of file
diff --git a/src/SimpleToolkit.SimpleShell/Handlers/NavigationHost/SimpleNavigationHostHandler.iOS.cs b/src/SimpleToolkit.SimpleShell/Handlers/NavigationHost/SimpleNavigationHostHandler.iOS.cs
index f6358b9..9545c25 100644
--- a/src/SimpleToolkit.SimpleShell/Handlers/NavigationHost/SimpleNavigationHostHandler.iOS.cs
+++ b/src/SimpleToolkit.SimpleShell/Handlers/NavigationHost/SimpleNavigationHostHandler.iOS.cs
@@ -16,6 +16,9 @@ public partial class SimpleNavigationHostHandler : ViewHandler
{
protected virtual AView GetNavigationHostContent()
{
- return (navigationHost?.Handler as SimpleNavigationHostHandler)?.Container.GetChildAt(0);
+ return (navigationHost?.Handler as SimpleNavigationHostHandler)?.Container?.GetChildAt(0);
}
}
}
diff --git a/src/SimpleToolkit.SimpleShell/Handlers/Shell/SimpleShellHandler.Shared.cs b/src/SimpleToolkit.SimpleShell/Handlers/SimpleShell/SimpleShellHandler.Shared.cs
similarity index 77%
rename from src/SimpleToolkit.SimpleShell/Handlers/Shell/SimpleShellHandler.Shared.cs
rename to src/SimpleToolkit.SimpleShell/Handlers/SimpleShell/SimpleShellHandler.Shared.cs
index 0d24f98..8290d50 100644
--- a/src/SimpleToolkit.SimpleShell/Handlers/Shell/SimpleShellHandler.Shared.cs
+++ b/src/SimpleToolkit.SimpleShell/Handlers/SimpleShell/SimpleShellHandler.Shared.cs
@@ -1,19 +1,20 @@
-using Microsoft.Maui.Handlers;
+#if ANDROID || IOS || MACCATALYST || WINDOWS
+
+using Microsoft.Maui.Handlers;
using Microsoft.Maui.Platform;
+using SimpleToolkit.SimpleShell.Extensions;
#if ANDROID
using PlatformShell = Android.Views.View;
-#elif __IOS__ || MACCATALYST
+#elif IOS || MACCATALYST
using PlatformShell = UIKit.UIView;
#elif WINDOWS
using PlatformShell = Microsoft.UI.Xaml.FrameworkElement;
-#elif (NETSTANDARD || !PLATFORM) || (NET6_0_OR_GREATER && !IOS && !ANDROID && !TIZEN)
+#else
using PlatformShell = System.Object;
#endif
namespace SimpleToolkit.SimpleShell.Handlers
{
-#if ANDROID || __IOS__ || MACCATALYST || WINDOWS
-
public partial class SimpleShellHandler
{
public static IPropertyMapper Mapper = new PropertyMapper(ViewHandler.ViewMapper)
@@ -43,10 +44,7 @@ public SimpleShellHandler()
protected override PlatformShell CreatePlatformView()
{
- if (VirtualView.Content is null)
- {
- throw new ArgumentNullException("Content property cannot be null");
- }
+ _ = VirtualView.Content ?? throw new ArgumentNullException("Content property cannot be null");
var content = VirtualView.Content.ToPlatform(MauiContext);
@@ -90,26 +88,11 @@ protected virtual SimpleShellItemHandler CreateShellItemHandler()
return itemHandler;
}
- private static void MapCurrentItem(SimpleShellHandler handler, ISimpleShell shell)
+ public static void MapCurrentItem(SimpleShellHandler handler, ISimpleShell shell)
{
handler.SwitchShellItem(shell.CurrentItem, true);
}
}
-
-#else
-
- public partial class SimpleShellHandler : ElementHandler
- {
- public SimpleShellHandler(IPropertyMapper mapper, CommandMapper commandMapper)
- : base(mapper, commandMapper)
- {
- }
-
- protected override System.Object CreatePlatformElement()
- {
- throw new NotImplementedException();
- }
- }
-
-#endif
}
+
+#endif
\ No newline at end of file
diff --git a/src/SimpleToolkit.SimpleShell/Handlers/SimpleShell/SimpleShellHandler.Standard.cs b/src/SimpleToolkit.SimpleShell/Handlers/SimpleShell/SimpleShellHandler.Standard.cs
new file mode 100644
index 0000000..5ca2c6c
--- /dev/null
+++ b/src/SimpleToolkit.SimpleShell/Handlers/SimpleShell/SimpleShellHandler.Standard.cs
@@ -0,0 +1,21 @@
+#if !(ANDROID || __IOS__ || MACCATALYST || WINDOWS)
+
+using Microsoft.Maui.Handlers;
+
+namespace SimpleToolkit.SimpleShell.Handlers
+{
+ public partial class SimpleShellHandler : ElementHandler
+ {
+ public SimpleShellHandler(IPropertyMapper mapper, CommandMapper commandMapper)
+ : base(mapper, commandMapper)
+ {
+ }
+
+ protected override System.Object CreatePlatformElement()
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
+
+#endif
\ No newline at end of file
diff --git a/src/SimpleToolkit.SimpleShell/Handlers/Shell/SimpleShellHandler.Windows.cs b/src/SimpleToolkit.SimpleShell/Handlers/SimpleShell/SimpleShellHandler.Windows.cs
similarity index 93%
rename from src/SimpleToolkit.SimpleShell/Handlers/Shell/SimpleShellHandler.Windows.cs
rename to src/SimpleToolkit.SimpleShell/Handlers/SimpleShell/SimpleShellHandler.Windows.cs
index 9c8660f..7062564 100644
--- a/src/SimpleToolkit.SimpleShell/Handlers/Shell/SimpleShellHandler.Windows.cs
+++ b/src/SimpleToolkit.SimpleShell/Handlers/SimpleShell/SimpleShellHandler.Windows.cs
@@ -1,7 +1,6 @@
#if WINDOWS
using Microsoft.Maui.Handlers;
-using Microsoft.Maui.Platform;
using WFrameworkElement = Microsoft.UI.Xaml.FrameworkElement;
namespace SimpleToolkit.SimpleShell.Handlers
diff --git a/src/SimpleToolkit.SimpleShell/Handlers/Shell/SimpleShellHandler.iOS.cs b/src/SimpleToolkit.SimpleShell/Handlers/SimpleShell/SimpleShellHandler.iOS.cs
similarity index 92%
rename from src/SimpleToolkit.SimpleShell/Handlers/Shell/SimpleShellHandler.iOS.cs
rename to src/SimpleToolkit.SimpleShell/Handlers/SimpleShell/SimpleShellHandler.iOS.cs
index ba456d0..47c9cf4 100644
--- a/src/SimpleToolkit.SimpleShell/Handlers/Shell/SimpleShellHandler.iOS.cs
+++ b/src/SimpleToolkit.SimpleShell/Handlers/SimpleShell/SimpleShellHandler.iOS.cs
@@ -1,4 +1,4 @@
-#if __IOS__ || MACCATALYST
+#if IOS || MACCATALYST
using Microsoft.Maui.Handlers;
using UIKit;
diff --git a/src/SimpleToolkit.SimpleShell/Handlers/ShellItem/SimpleShellItemHandler.Android.cs b/src/SimpleToolkit.SimpleShell/Handlers/SimpleShellItem/SimpleShellItemHandler.Android.cs
similarity index 91%
rename from src/SimpleToolkit.SimpleShell/Handlers/ShellItem/SimpleShellItemHandler.Android.cs
rename to src/SimpleToolkit.SimpleShell/Handlers/SimpleShellItem/SimpleShellItemHandler.Android.cs
index db950cb..04d5d7e 100644
--- a/src/SimpleToolkit.SimpleShell/Handlers/ShellItem/SimpleShellItemHandler.Android.cs
+++ b/src/SimpleToolkit.SimpleShell/Handlers/SimpleShellItem/SimpleShellItemHandler.Android.cs
@@ -6,7 +6,7 @@
namespace SimpleToolkit.SimpleShell.Handlers
{
- public partial class SimpleShellItemHandler : ElementHandler, IAppearanceObserver
+ public partial class SimpleShellItemHandler : ElementHandler
{
protected override CustomFrameLayout CreatePlatformElement()
{
diff --git a/src/SimpleToolkit.SimpleShell/Handlers/ShellItem/SimpleShellItemHandler.Shared.cs b/src/SimpleToolkit.SimpleShell/Handlers/SimpleShellItem/SimpleShellItemHandler.Shared.cs
similarity index 54%
rename from src/SimpleToolkit.SimpleShell/Handlers/ShellItem/SimpleShellItemHandler.Shared.cs
rename to src/SimpleToolkit.SimpleShell/Handlers/SimpleShellItem/SimpleShellItemHandler.Shared.cs
index 2717b04..4440b6e 100644
--- a/src/SimpleToolkit.SimpleShell/Handlers/ShellItem/SimpleShellItemHandler.Shared.cs
+++ b/src/SimpleToolkit.SimpleShell/Handlers/SimpleShellItem/SimpleShellItemHandler.Shared.cs
@@ -1,10 +1,7 @@
-using Microsoft.Maui.Handlers;
-using Microsoft.Maui.Platform;
+using Microsoft.Maui.Platform;
#if ANDROID
-using Microsoft.Maui.Controls.Platform.Compatibility;
-using Google.Android.Material.Navigation;
using SectionContainer = Microsoft.Maui.Controls.Platform.Compatibility.CustomFrameLayout;
-#elif __IOS__ || MACCATALYST
+#elif IOS || MACCATALYST
using SectionContainer = UIKit.UIView;
#elif WINDOWS
using SectionContainer = Microsoft.UI.Xaml.Controls.Border;
@@ -14,9 +11,7 @@
namespace SimpleToolkit.SimpleShell.Handlers
{
-#if ANDROID || __IOS__ || MACCATALYST || WINDOWS
-
- public partial class SimpleShellItemHandler
+ public partial class SimpleShellItemHandler : IAppearanceObserver
{
protected SectionContainer shellSectionContainer;
protected ShellSection currentShellSection;
@@ -44,38 +39,25 @@ public SimpleShellItemHandler()
}
+ public virtual void OnAppearanceChanged(ShellAppearance appearance)
+ {
+ }
+
protected void UpdateCurrentItem()
{
if (currentShellSection == VirtualView.CurrentItem)
return;
- if (currentShellSection != null)
- {
+ if (currentShellSection is not null)
currentShellSection.PropertyChanged -= OnCurrentShellSectionPropertyChanged;
- }
currentShellSection = VirtualView.CurrentItem;
- if (VirtualView.CurrentItem != null)
+ if (VirtualView.CurrentItem is not null)
{
currentShellSectionHandler ??= (SimpleShellSectionHandler)VirtualView.CurrentItem.ToHandler(MauiContext);
-#if ANDROID
- if (PlatformView != shellSectionContainer.GetChildAt(0))
- {
- shellSectionContainer.RemoveAllViews();
- shellSectionContainer.AddView(currentShellSectionHandler.PlatformView);
- }
-#elif __IOS__ || MACCATALYST
- if (PlatformView != (UIKit.UIView)shellSectionContainer.Subviews.FirstOrDefault())
- {
- shellSectionContainer.ClearSubviews();
- shellSectionContainer.AddSubview(currentShellSectionHandler.PlatformView);
- }
-#elif WINDOWS
- if (PlatformView != (Microsoft.UI.Xaml.Controls.Frame)shellSectionContainer.Child)
- shellSectionContainer.Child = currentShellSectionHandler.PlatformView;
-#endif
+ UpdateShellSectionContainerContent();
if (currentShellSectionHandler.VirtualView != VirtualView.CurrentItem)
currentShellSectionHandler.SetVirtualView(VirtualView.CurrentItem);
@@ -84,44 +66,41 @@ protected void UpdateCurrentItem()
//UpdateSearchHandler();
//MapMenuItems();
- if (currentShellSection != null)
- {
+ if (currentShellSection is not null)
currentShellSection.PropertyChanged += OnCurrentShellSectionPropertyChanged;
- }
}
- void OnCurrentShellSectionPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
+ private void UpdateShellSectionContainerContent()
{
-
+#if ANDROID
+ if (PlatformView != shellSectionContainer.GetChildAt(0))
+ {
+ shellSectionContainer.RemoveAllViews();
+ shellSectionContainer.AddView(currentShellSectionHandler.PlatformView);
+ }
+#elif IOS || MACCATALYST
+ if (PlatformView != (UIKit.UIView)shellSectionContainer.Subviews.FirstOrDefault())
+ {
+ shellSectionContainer.ClearSubviews();
+ shellSectionContainer.AddSubview(currentShellSectionHandler.PlatformView);
+ }
+#elif WINDOWS
+ if (PlatformView != (Microsoft.UI.Xaml.Controls.Frame)shellSectionContainer.Child)
+ shellSectionContainer.Child = currentShellSectionHandler.PlatformView;
+#endif
}
- public void OnAppearanceChanged(ShellAppearance appearance)
+ private void OnCurrentShellSectionPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
}
- private static void MapTabBarIsVisible(SimpleShellItemHandler handler, ShellItem item)
+ public static void MapTabBarIsVisible(SimpleShellItemHandler handler, ShellItem item)
{
}
- private static void MapCurrentItem(SimpleShellItemHandler handler, ShellItem item)
+ public static void MapCurrentItem(SimpleShellItemHandler handler, ShellItem item)
{
handler.UpdateCurrentItem();
}
}
-
-#else
-
- public partial class SimpleShellItemHandler : ElementHandler
- {
- public SimpleShellItemHandler(IPropertyMapper mapper, CommandMapper commandMapper)
- : base(mapper, commandMapper)
- {
- }
-
- protected override System.Object CreatePlatformElement()
- {
- throw new NotImplementedException();
- }
- }
-#endif
}
diff --git a/src/SimpleToolkit.SimpleShell/Handlers/SimpleShellItem/SimpleShellItemHandler.Standard.cs b/src/SimpleToolkit.SimpleShell/Handlers/SimpleShellItem/SimpleShellItemHandler.Standard.cs
new file mode 100644
index 0000000..5e211bd
--- /dev/null
+++ b/src/SimpleToolkit.SimpleShell/Handlers/SimpleShellItem/SimpleShellItemHandler.Standard.cs
@@ -0,0 +1,16 @@
+#if !(ANDROID || IOS || MACCATALYST || WINDOWS)
+
+using Microsoft.Maui.Handlers;
+
+namespace SimpleToolkit.SimpleShell.Handlers
+{
+ public partial class SimpleShellItemHandler : ElementHandler
+ {
+ protected override System.Object CreatePlatformElement()
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
+
+#endif
\ No newline at end of file
diff --git a/src/SimpleToolkit.SimpleShell/Handlers/ShellItem/SimpleShellItemHandler.Windows.cs b/src/SimpleToolkit.SimpleShell/Handlers/SimpleShellItem/SimpleShellItemHandler.Windows.cs
similarity index 75%
rename from src/SimpleToolkit.SimpleShell/Handlers/ShellItem/SimpleShellItemHandler.Windows.cs
rename to src/SimpleToolkit.SimpleShell/Handlers/SimpleShellItem/SimpleShellItemHandler.Windows.cs
index 7d30403..e4f62f8 100644
--- a/src/SimpleToolkit.SimpleShell/Handlers/ShellItem/SimpleShellItemHandler.Windows.cs
+++ b/src/SimpleToolkit.SimpleShell/Handlers/SimpleShellItem/SimpleShellItemHandler.Windows.cs
@@ -1,12 +1,11 @@
#if WINDOWS
-// || (NETSTANDARD || !PLATFORM) || (NET6_0_OR_GREATER && !IOS && !ANDROID && !TIZEN)
using Microsoft.Maui.Handlers;
using WBorder = Microsoft.UI.Xaml.Controls.Border;
namespace SimpleToolkit.SimpleShell.Handlers
{
- public partial class SimpleShellItemHandler : ElementHandler, IAppearanceObserver
+ public partial class SimpleShellItemHandler : ElementHandler
{
protected override WBorder CreatePlatformElement()
{
diff --git a/src/SimpleToolkit.SimpleShell/Handlers/ShellItem/SimpleShellItemHandler.iOS.cs b/src/SimpleToolkit.SimpleShell/Handlers/SimpleShellItem/SimpleShellItemHandler.iOS.cs
similarity index 83%
rename from src/SimpleToolkit.SimpleShell/Handlers/ShellItem/SimpleShellItemHandler.iOS.cs
rename to src/SimpleToolkit.SimpleShell/Handlers/SimpleShellItem/SimpleShellItemHandler.iOS.cs
index a426ac5..c103cc9 100644
--- a/src/SimpleToolkit.SimpleShell/Handlers/ShellItem/SimpleShellItemHandler.iOS.cs
+++ b/src/SimpleToolkit.SimpleShell/Handlers/SimpleShellItem/SimpleShellItemHandler.iOS.cs
@@ -1,11 +1,11 @@
-#if __IOS__ || MACCATALYST
+#if IOS || MACCATALYST
using Microsoft.Maui.Handlers;
using UIKit;
namespace SimpleToolkit.SimpleShell.Handlers
{
- public partial class SimpleShellItemHandler : ElementHandler, IAppearanceObserver
+ public partial class SimpleShellItemHandler : ElementHandler
{
protected override UIView CreatePlatformElement()
{
diff --git a/src/SimpleToolkit.SimpleShell/Handlers/ShellSection/SimpleShellSectionHandler.Android.cs b/src/SimpleToolkit.SimpleShell/Handlers/SimpleShellSection/SimpleShellSectionHandler.Android.cs
similarity index 90%
rename from src/SimpleToolkit.SimpleShell/Handlers/ShellSection/SimpleShellSectionHandler.Android.cs
rename to src/SimpleToolkit.SimpleShell/Handlers/SimpleShellSection/SimpleShellSectionHandler.Android.cs
index 49f147d..1e01397 100644
--- a/src/SimpleToolkit.SimpleShell/Handlers/ShellSection/SimpleShellSectionHandler.Android.cs
+++ b/src/SimpleToolkit.SimpleShell/Handlers/SimpleShellSection/SimpleShellSectionHandler.Android.cs
@@ -6,7 +6,7 @@
namespace SimpleToolkit.SimpleShell.Handlers
{
- public partial class SimpleShellSectionHandler : ElementHandler, IAppearanceObserver
+ public partial class SimpleShellSectionHandler : ElementHandler
{
protected override CustomFrameLayout CreatePlatformElement()
{
diff --git a/src/SimpleToolkit.SimpleShell/Handlers/ShellSection/SimpleShellSectionHandler.Shared.cs b/src/SimpleToolkit.SimpleShell/Handlers/SimpleShellSection/SimpleShellSectionHandler.Shared.cs
similarity index 70%
rename from src/SimpleToolkit.SimpleShell/Handlers/ShellSection/SimpleShellSectionHandler.Shared.cs
rename to src/SimpleToolkit.SimpleShell/Handlers/SimpleShellSection/SimpleShellSectionHandler.Shared.cs
index ecaa475..e7f60a2 100644
--- a/src/SimpleToolkit.SimpleShell/Handlers/ShellSection/SimpleShellSectionHandler.Shared.cs
+++ b/src/SimpleToolkit.SimpleShell/Handlers/SimpleShellSection/SimpleShellSectionHandler.Shared.cs
@@ -1,4 +1,4 @@
-using Microsoft.Maui.Handlers;
+using SimpleToolkit.SimpleShell.Extensions;
using SimpleToolkit.SimpleShell.NavigationManager;
#if ANDROID
using PageContainer = Microsoft.Maui.Controls.Platform.Compatibility.CustomFrameLayout;
@@ -12,31 +12,29 @@
namespace SimpleToolkit.SimpleShell.Handlers
{
-#if ANDROID || __IOS__ || MACCATALYST || WINDOWS
-
- public partial class SimpleShellSectionHandler
+ public partial class SimpleShellSectionHandler : IAppearanceObserver
{
- protected SimpleStackNavigationManager navigationManager;
- protected ShellSection shellSection;
-
public static PropertyMapper Mapper =
- new PropertyMapper(ElementMapper)
- {
- [nameof(ShellSection.CurrentItem)] = MapCurrentItem,
- };
+ new PropertyMapper(ElementMapper)
+ {
+ [nameof(ShellSection.CurrentItem)] = MapCurrentItem,
+ };
public static CommandMapper CommandMapper =
- new CommandMapper(ElementCommandMapper)
- {
- [nameof(IStackNavigation.RequestNavigation)] = RequestNavigation
- };
+ new CommandMapper(ElementCommandMapper)
+ {
+ [nameof(IStackNavigation.RequestNavigation)] = RequestNavigation
+ };
+
+ protected SimpleStackNavigationManager navigationManager;
+ protected ShellSection shellSection;
+
public SimpleShellSectionHandler(IPropertyMapper mapper, CommandMapper commandMapper)
: base(mapper ?? Mapper, commandMapper ?? CommandMapper)
{
}
-
public SimpleShellSectionHandler() : base(Mapper, CommandMapper)
{
}
@@ -44,7 +42,7 @@ public SimpleShellSectionHandler() : base(Mapper, CommandMapper)
public override void SetVirtualView(IElement view)
{
- if (shellSection != null)
+ if (shellSection is not null)
{
((IShellSectionController)shellSection).NavigationRequested -= OnNavigationRequested;
((IShellController)shellSection.FindParentOfType()).RemoveAppearanceObserver(this);
@@ -53,7 +51,7 @@ public override void SetVirtualView(IElement view)
// If we've already connected to the navigation manager
// then we need to make sure to disconnect and connect up to
// the new incoming virtual view
- if (navigationManager?.StackNavigation != null &&
+ if (navigationManager?.StackNavigation is not null &&
navigationManager.StackNavigation != view)
{
navigationManager.Disconnect(navigationManager.StackNavigation, PlatformView);
@@ -67,13 +65,17 @@ public override void SetVirtualView(IElement view)
base.SetVirtualView(view);
shellSection = (ShellSection)view;
- if (shellSection != null)
+ if (shellSection is not null)
{
((IShellSectionController)shellSection).NavigationRequested += OnNavigationRequested;
((IShellController)shellSection.FindParentOfType()).AddAppearanceObserver(this, shellSection);
}
}
+ public virtual void OnAppearanceChanged(ShellAppearance appearance)
+ {
+ }
+
protected override void ConnectHandler(PageContainer platformView)
{
navigationManager?.Connect(VirtualView, platformView);
@@ -96,40 +98,31 @@ void OnNavigationRequested(object sender, object e)
protected virtual void SyncNavigationStack(bool animated)
{
- // TODO: There is another bug. Maybe try to compare the NavigationStack with current Shell (or VirtualView) state
- //var shell = VirtualView.FindParentOfType();
- //var state = shell.CurrentState;
-
- List pageStack = new List()
+ var pageStack = new List()
{
(VirtualView.CurrentItem as IShellContentController).GetOrCreateContent()
};
- // When navigating from subtab with a navigation stack to another subtab in the same tab, there is NavigationStack of previous subtab in VirtualView.Navigation
+ // When navigating from a subtab with a navigation stack to another subtab in the same tab, there is a NavigationStack of the previous subtab in VirtualView.Navigation
if (currentShellContent == VirtualView.CurrentItem && !navigationStackCanBeAdded) // This is just a workaround of the bug in Shell
for (var i = 1; i < VirtualView.Navigation.NavigationStack.Count; i++)
{
pageStack.Add(VirtualView.Navigation.NavigationStack[i]);
}
- navigationStackCanBeAdded = currentShellContent != null && VirtualView.Navigation.NavigationStack.Count > 1 && currentShellContent != VirtualView.CurrentItem; // This is just a workaround of the bug in Shell
+ navigationStackCanBeAdded = currentShellContent is not null && VirtualView.Navigation.NavigationStack.Count > 1 && currentShellContent != VirtualView.CurrentItem; // This is just a workaround of the bug in Shell
currentShellContent = VirtualView.CurrentItem; // This is just a workaround of the bug in Shell
// The point of this is to push the shell navigation over to using the INavigationStack
// work flow. Ideally we rewrite all the push/pop/etc.. parts inside ShellSection.cs
// to just use INavigationStack but that will be easier once all platforms are using
// ShellHandler
- (VirtualView as IStackNavigation)
- .RequestNavigation(new NavigationRequest(pageStack, animated));
+ (VirtualView as IStackNavigation).RequestNavigation(new NavigationRequest(pageStack, animated));
}
protected virtual SimpleStackNavigationManager CreateNavigationManager() =>
navigationManager ??= new SimpleStackNavigationManager(MauiContext ?? throw new InvalidOperationException("MauiContext cannot be null"));
- public void OnAppearanceChanged(ShellAppearance appearance)
- {
- }
-
public static void RequestNavigation(SimpleShellSectionHandler handler, IStackNavigation view, object arg3)
{
if (arg3 is NavigationRequest nr)
@@ -147,21 +140,4 @@ public static void MapCurrentItem(SimpleShellSectionHandler handler, ShellSectio
handler.SyncNavigationStack(false);
}
}
-
-#else
-
- public partial class SimpleShellSectionHandler : ElementHandler
- {
- public SimpleShellSectionHandler(IPropertyMapper mapper, CommandMapper commandMapper)
- : base(mapper, commandMapper)
- {
- }
-
- protected override System.Object CreatePlatformElement()
- {
- throw new NotImplementedException();
- }
- }
-
-#endif
}
diff --git a/src/SimpleToolkit.SimpleShell/Handlers/SimpleShellSection/SimpleShellSectionHandler.Standard.cs b/src/SimpleToolkit.SimpleShell/Handlers/SimpleShellSection/SimpleShellSectionHandler.Standard.cs
new file mode 100644
index 0000000..8e1febe
--- /dev/null
+++ b/src/SimpleToolkit.SimpleShell/Handlers/SimpleShellSection/SimpleShellSectionHandler.Standard.cs
@@ -0,0 +1,16 @@
+#if !(ANDROID || IOS || MACCATALYST || WINDOWS)
+
+using Microsoft.Maui.Handlers;
+
+namespace SimpleToolkit.SimpleShell.Handlers
+{
+ public partial class SimpleShellSectionHandler : ElementHandler
+ {
+ protected override System.Object CreatePlatformElement()
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
+
+#endif
\ No newline at end of file
diff --git a/src/SimpleToolkit.SimpleShell/Handlers/ShellSection/SimpleShellSectionHandler.Windows.cs b/src/SimpleToolkit.SimpleShell/Handlers/SimpleShellSection/SimpleShellSectionHandler.Windows.cs
similarity index 89%
rename from src/SimpleToolkit.SimpleShell/Handlers/ShellSection/SimpleShellSectionHandler.Windows.cs
rename to src/SimpleToolkit.SimpleShell/Handlers/SimpleShellSection/SimpleShellSectionHandler.Windows.cs
index f3f35c8..71a7a9a 100644
--- a/src/SimpleToolkit.SimpleShell/Handlers/ShellSection/SimpleShellSectionHandler.Windows.cs
+++ b/src/SimpleToolkit.SimpleShell/Handlers/SimpleShellSection/SimpleShellSectionHandler.Windows.cs
@@ -5,7 +5,7 @@
namespace SimpleToolkit.SimpleShell.Handlers
{
- public partial class SimpleShellSectionHandler : ElementHandler, IAppearanceObserver
+ public partial class SimpleShellSectionHandler : ElementHandler
{
protected override WFrame CreatePlatformElement()
{
diff --git a/src/SimpleToolkit.SimpleShell/Handlers/ShellSection/SimpleShellSectionHandler.iOS.cs b/src/SimpleToolkit.SimpleShell/Handlers/SimpleShellSection/SimpleShellSectionHandler.iOS.cs
similarity index 83%
rename from src/SimpleToolkit.SimpleShell/Handlers/ShellSection/SimpleShellSectionHandler.iOS.cs
rename to src/SimpleToolkit.SimpleShell/Handlers/SimpleShellSection/SimpleShellSectionHandler.iOS.cs
index 6b3bd7d..b63c5c3 100644
--- a/src/SimpleToolkit.SimpleShell/Handlers/ShellSection/SimpleShellSectionHandler.iOS.cs
+++ b/src/SimpleToolkit.SimpleShell/Handlers/SimpleShellSection/SimpleShellSectionHandler.iOS.cs
@@ -1,11 +1,11 @@
-#if __IOS__ || MACCATALYST
+#if IOS || MACCATALYST
using Microsoft.Maui.Handlers;
using UIKit;
namespace SimpleToolkit.SimpleShell.Handlers
{
- public partial class SimpleShellSectionHandler : ElementHandler, IAppearanceObserver
+ public partial class SimpleShellSectionHandler : ElementHandler
{
protected override UIView CreatePlatformElement()
{
diff --git a/src/SimpleToolkit.SimpleShell/NavigationManager/SimpleStackNavigationManager.cs b/src/SimpleToolkit.SimpleShell/NavigationManager/SimpleStackNavigationManager.cs
index f836cb7..a2b99d7 100644
--- a/src/SimpleToolkit.SimpleShell/NavigationManager/SimpleStackNavigationManager.cs
+++ b/src/SimpleToolkit.SimpleShell/NavigationManager/SimpleStackNavigationManager.cs
@@ -25,11 +25,13 @@ public class SimpleStackNavigationManager
public IStackNavigation StackNavigation { get; protected set; }
public IReadOnlyList NavigationStack { get; protected set; } = new List();
+
public SimpleStackNavigationManager(IMauiContext mauiContext)
{
this.mauiContext = mauiContext;
}
+
public virtual void Connect(IStackNavigation navigationView, NavFrame navigationFrame)
{
this.navigationFrame = navigationFrame;
@@ -102,7 +104,7 @@ protected virtual PlatformPage GetPageView(IView page)
return pageView;
}
- void FireNavigationFinished()
+ private void FireNavigationFinished()
{
StackNavigation?.NavigationFinished(NavigationStack);
}
diff --git a/src/SimpleToolkit.SimpleShell/SimpleToolkit.SimpleShell.csproj b/src/SimpleToolkit.SimpleShell/SimpleToolkit.SimpleShell.csproj
index 6475a3d..009d077 100644
--- a/src/SimpleToolkit.SimpleShell/SimpleToolkit.SimpleShell.csproj
+++ b/src/SimpleToolkit.SimpleShell/SimpleToolkit.SimpleShell.csproj
@@ -1,4 +1,4 @@
-
+
net6.0;net6.0-android;net6.0-ios;net6.0-maccatalyst
@@ -15,6 +15,22 @@
10.0.17763.0
10.0.17763.0
6.5
+
+ SimpleToolkit.SimpleShell
+ SimpleToolkit.SimpleShell
+ LICENSE
+ MAUI, Controls, Shell, Navigation
+ RadekVyM
+ ..\..\packages
+ 1.0.0
+ -preview1
+ $(VersionPrefix)$(VersionSuffix)
+ Simplified implementation of .NET MAUI Shell that is part of SimpleToolkit library.
+ https://github.com/RadekVyM/SimpleToolkit
+ https://github.com/RadekVyM/SimpleToolkit
+ git
+ logo_with_background.png
+ Copyright © RadekVyM and contributors
@@ -24,4 +40,15 @@
+
+
+ True
+ \
+
+
+ True
+ \
+
+
+
diff --git a/src/SimpleToolkit.SimpleShell/Views/ISimpleShell.cs b/src/SimpleToolkit.SimpleShell/Views/ISimpleShell.cs
deleted file mode 100644
index 6d804c8..0000000
--- a/src/SimpleToolkit.SimpleShell/Views/ISimpleShell.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-namespace SimpleToolkit.SimpleShell
-{
- public interface ISimpleShell : IFlyoutView, IView, IElement, ITransform, IShellController, IPageController, IVisualElementController, IElementController, IPageContainer
- {
- IView Content { get; set; }
- ShellItem CurrentItem { get; set; }
- }
-}
diff --git a/src/SimpleToolkit.SimpleShell/Views/SimpleNavigationHost/ISimpleNavigationHost.cs b/src/SimpleToolkit.SimpleShell/Views/SimpleNavigationHost/ISimpleNavigationHost.cs
new file mode 100644
index 0000000..7c11fed
--- /dev/null
+++ b/src/SimpleToolkit.SimpleShell/Views/SimpleNavigationHost/ISimpleNavigationHost.cs
@@ -0,0 +1,9 @@
+namespace SimpleToolkit.SimpleShell
+{
+ ///
+ /// A container for pages in a .
+ ///
+ public interface ISimpleNavigationHost : IView
+ {
+ }
+}
diff --git a/src/SimpleToolkit.SimpleShell/Views/SimpleNavigationHost.cs b/src/SimpleToolkit.SimpleShell/Views/SimpleNavigationHost/SimpleNavigationHost.cs
similarity index 55%
rename from src/SimpleToolkit.SimpleShell/Views/SimpleNavigationHost.cs
rename to src/SimpleToolkit.SimpleShell/Views/SimpleNavigationHost/SimpleNavigationHost.cs
index c324b08..b7bb9f1 100644
--- a/src/SimpleToolkit.SimpleShell/Views/SimpleNavigationHost.cs
+++ b/src/SimpleToolkit.SimpleShell/Views/SimpleNavigationHost/SimpleNavigationHost.cs
@@ -1,9 +1,8 @@
namespace SimpleToolkit.SimpleShell
{
- public interface ISimpleNavigationHost : IView
- {
- }
-
+ ///
+ /// A container for pages in a .
+ ///
public class SimpleNavigationHost : View, ISimpleNavigationHost
{
}
diff --git a/src/SimpleToolkit.SimpleShell/Views/SimpleShell/ISimpleShell.cs b/src/SimpleToolkit.SimpleShell/Views/SimpleShell/ISimpleShell.cs
new file mode 100644
index 0000000..3b1ae36
--- /dev/null
+++ b/src/SimpleToolkit.SimpleShell/Views/SimpleShell/ISimpleShell.cs
@@ -0,0 +1,37 @@
+namespace SimpleToolkit.SimpleShell
+{
+ ///
+ /// A shell that lets you define your custom navigation experience.
+ ///
+ public interface ISimpleShell : IFlyoutView, IView, IElement, ITransform, IShellController, IPageController, IVisualElementController, IElementController, IPageContainer
+ {
+ ///
+ /// Gets or sets the content of this shell.
+ ///
+ IView Content { get; set; }
+ ///
+ /// The currently selected .
+ ///
+ new Page CurrentPage { get; }
+ ///
+ /// The currently selected or .
+ ///
+ ShellItem CurrentItem { get; set; }
+ ///
+ /// The currently selected .
+ ///
+ ShellContent CurrentShellContent { get; }
+ ///
+ /// The currently selected .
+ ///
+ ShellSection CurrentShellSection { get; }
+ ///
+ /// All items of this shell.
+ ///
+ IReadOnlyList ShellSections { get; }
+ ///
+ /// All items of this shell.
+ ///
+ IReadOnlyList ShellContents { get; }
+ }
+}
diff --git a/src/SimpleToolkit.SimpleShell/Views/SimpleShell.cs b/src/SimpleToolkit.SimpleShell/Views/SimpleShell/SimpleShell.cs
similarity index 79%
rename from src/SimpleToolkit.SimpleShell/Views/SimpleShell.cs
rename to src/SimpleToolkit.SimpleShell/Views/SimpleShell/SimpleShell.cs
index a21b5ff..2ff88e2 100644
--- a/src/SimpleToolkit.SimpleShell/Views/SimpleShell.cs
+++ b/src/SimpleToolkit.SimpleShell/Views/SimpleShell/SimpleShell.cs
@@ -1,11 +1,16 @@
-namespace SimpleToolkit.SimpleShell
+using SimpleToolkit.SimpleShell.Extensions;
+
+namespace SimpleToolkit.SimpleShell
{
// TODO: It looks like the toolbar is part of ShellSection on iOS. So it is missing in my implementation. How to solve it?
// 1) Lets hope that the toolbar will be handled as on Android and Windows when Shell totally transitions to handler architecture
// 2) Implement it myself in my SimpleShellSectionHandler - This can be a waste of time if 1) comes true
// I am waiting for transition to handler architecture and then I will see
// I have set default visibility of the toolbar to hidden for now
-
+
+ ///
+ /// An implementation of that lets you define your custom navigation experience.
+ ///
public class SimpleShell : Shell, ISimpleShell
{
const string PageStateNamePrefix = "SimplePageState";
@@ -26,6 +31,8 @@ public class SimpleShell : Shell, ISimpleShell
public static readonly BindableProperty ShellSectionsProperty = BindableProperty.Create(nameof(ShellSections), typeof(IReadOnlyList), typeof(SimpleShell), defaultBindingMode: BindingMode.OneWay);
public static readonly BindableProperty ShellContentsProperty = BindableProperty.Create(nameof(ShellContents), typeof(IReadOnlyList), typeof(SimpleShell), defaultBindingMode: BindingMode.OneWay);
+ public static new SimpleShell Current => Shell.Current as SimpleShell;
+
public virtual IView Content
{
get => (IView)GetValue(ContentProperty);
@@ -35,35 +42,33 @@ public virtual IView Content
public new Page CurrentPage
{
get => (Page)GetValue(CurrentPageProperty);
- private set => SetValue(CurrentPageProperty, value);
+ protected set => SetValue(CurrentPageProperty, value);
}
public ShellContent CurrentShellContent
{
get => (ShellContent)GetValue(CurrentShellContentProperty);
- private set => SetValue(CurrentShellContentProperty, value);
+ protected set => SetValue(CurrentShellContentProperty, value);
}
public ShellSection CurrentShellSection
{
get => (ShellSection)GetValue(CurrentShellSectionProperty);
- private set => SetValue(CurrentShellSectionProperty, value);
+ protected set => SetValue(CurrentShellSectionProperty, value);
}
public IReadOnlyList ShellSections
{
get => (IReadOnlyList)GetValue(ShellSectionsProperty);
- private set => SetValue(ShellSectionsProperty, value);
+ protected set => SetValue(ShellSectionsProperty, value);
}
public IReadOnlyList ShellContents
{
get => (IReadOnlyList)GetValue(ShellContentsProperty);
- private set => SetValue(ShellContentsProperty, value);
+ protected set => SetValue(ShellContentsProperty, value);
}
- public new SimpleShell Current => Shell.Current as SimpleShell;
-
public SimpleShell()
{
@@ -104,47 +109,6 @@ private void UpdateVisualState(string state, string statePrefix, string groupNam
VisualStateManager.GoToState(this, statePrefix);
}
- private void SimpleShellDescendantChanged(object sender, ElementEventArgs e)
- {
- // Update collections if logical structure of Shell is changed
- if (e.Element is BaseShellItem)
- {
- ShellSections = GetShellSections().ToList();
- ShellContents = GetShellContents().ToList();
- }
- }
-
- private void SimpleShellLoaded(object sender, EventArgs e)
- {
- SetDefaultShellPropertyValues();
- UpdateVisualStates();
-
- ShellSections = GetShellSections().ToList();
- ShellContents = GetShellContents().ToList();
- DescendantAdded += SimpleShellDescendantChanged;
- DescendantRemoved += SimpleShellDescendantChanged;
- }
-
- private void SimpleShellNavigated(object sender, ShellNavigatedEventArgs e)
- {
- SetDefaultShellPropertyValues();
-
- CurrentPage = base.CurrentPage;
- CurrentShellSection = CurrentItem?.CurrentItem;
- CurrentShellContent = CurrentItem?.CurrentItem?.CurrentItem;
- // If BackButtonBehavior is not set on CurrentPage, set BackButtonBehavior of the Shell
- if (!CurrentPage.IsSet(Shell.BackButtonBehaviorProperty))
- {
- Shell.SetBackButtonBehavior(CurrentPage, Shell.GetBackButtonBehavior(this));
- }
- if (!CurrentPage.IsSet(Shell.NavBarIsVisibleProperty))
- {
- Shell.SetNavBarIsVisible(CurrentPage, Shell.GetNavBarIsVisible(this));
- }
-
- UpdateVisualStates();
- }
-
private void SetDefaultShellPropertyValues()
{
if (defaultShellPropertyValuesSet)
@@ -162,30 +126,13 @@ private void SetDefaultShellPropertyValues()
defaultShellPropertyValuesSet = true;
}
- private void SimpleShellUnloaded(object sender, EventArgs e)
- {
- Navigated -= SimpleShellNavigated;
- Unloaded -= SimpleShellUnloaded;
- Loaded -= SimpleShellLoaded;
- DescendantAdded -= SimpleShellDescendantChanged;
- DescendantRemoved -= SimpleShellDescendantChanged;
- }
-
- private static void OnContentChanged(BindableObject bindable, object oldValue, object newValue)
- {
- if (bindable is SimpleShell simpleShell)
- {
- simpleShell.UpdateVisualStates();
- }
- }
-
private IEnumerable GetShellSections()
{
var list = new HashSet();
foreach (var shellItem in Items)
{
- var shellSections = GetShellSections(shellItem);
+ var shellSections = shellItem.GetShellSections();
foreach (var section in shellSections)
list.Add(section);
}
@@ -193,34 +140,13 @@ private IEnumerable GetShellSections()
return list;
}
- private IEnumerable GetShellSections(BaseShellItem baseShellItem)
- {
- var list = new HashSet();
-
- if (baseShellItem is ShellSection shellSection)
- {
- list.Add(shellSection);
- }
- else if (baseShellItem is ShellItem shellItem)
- {
- foreach (var item in shellItem.Items)
- {
- var shellSections = GetShellSections(item);
- foreach (var section in shellSections)
- list.Add(section);
- }
- }
-
- return list;
- }
-
private IEnumerable GetShellContents()
{
var list = new HashSet();
foreach (var shellItem in Items)
{
- var shellContents = GetShellContents(shellItem);
+ var shellContents = shellItem.GetShellContents();
foreach (var content in shellContents)
list.Add(content);
}
@@ -228,30 +154,62 @@ private IEnumerable GetShellContents()
return list;
}
- private IEnumerable GetShellContents(BaseShellItem baseShellItem)
+ private void SimpleShellNavigated(object sender, ShellNavigatedEventArgs e)
{
- var list = new HashSet();
+ SetDefaultShellPropertyValues();
- if (baseShellItem is ShellContent shellContent)
+ CurrentPage = base.CurrentPage;
+ CurrentShellSection = CurrentItem?.CurrentItem;
+ CurrentShellContent = CurrentItem?.CurrentItem?.CurrentItem;
+ // If BackButtonBehavior is not set on CurrentPage, set BackButtonBehavior of the Shell
+ if (!CurrentPage.IsSet(Shell.BackButtonBehaviorProperty))
{
- list.Add(shellContent);
+ Shell.SetBackButtonBehavior(CurrentPage, Shell.GetBackButtonBehavior(this));
}
- else if (baseShellItem is ShellItem shellItem)
+ if (!CurrentPage.IsSet(Shell.NavBarIsVisibleProperty))
{
- foreach (var item in shellItem.Items)
- {
- var shellContents = GetShellContents(item);
- foreach (var content in shellContents)
- list.Add(content);
- }
+ Shell.SetNavBarIsVisible(CurrentPage, Shell.GetNavBarIsVisible(this));
}
- else if (baseShellItem is ShellSection shellSection)
+
+ UpdateVisualStates();
+ }
+
+ private void SimpleShellDescendantChanged(object sender, ElementEventArgs e)
+ {
+ // Update collections if logical structure of the shell changes
+ if (e.Element is BaseShellItem)
{
- foreach (var content in shellSection.Items)
- list.Add(content);
+ ShellSections = GetShellSections().ToList();
+ ShellContents = GetShellContents().ToList();
}
+ }
- return list;
+ private void SimpleShellLoaded(object sender, EventArgs e)
+ {
+ SetDefaultShellPropertyValues();
+ UpdateVisualStates();
+
+ ShellSections = GetShellSections().ToList();
+ ShellContents = GetShellContents().ToList();
+ DescendantAdded += SimpleShellDescendantChanged;
+ DescendantRemoved += SimpleShellDescendantChanged;
+ }
+
+ private void SimpleShellUnloaded(object sender, EventArgs e)
+ {
+ Navigated -= SimpleShellNavigated;
+ Unloaded -= SimpleShellUnloaded;
+ Loaded -= SimpleShellLoaded;
+ DescendantAdded -= SimpleShellDescendantChanged;
+ DescendantRemoved -= SimpleShellDescendantChanged;
+ }
+
+ private static void OnContentChanged(BindableObject bindable, object oldValue, object newValue)
+ {
+ if (bindable is SimpleShell simpleShell)
+ {
+ simpleShell.UpdateVisualStates();
+ }
}
}
}