Skip to content

Commit

Permalink
Merge pull request #46 from naveenkumar-sanjeevirayan/BottomSheetChanges
Browse files Browse the repository at this point in the history
Implementation of the SfBottomSheet Control in MAUI Toolkit
  • Loading branch information
PaulAndersonS authored Dec 4, 2024
2 parents d9c24df + 6e8de01 commit 7cb6532
Show file tree
Hide file tree
Showing 10 changed files with 2,906 additions and 4 deletions.
1 change: 1 addition & 0 deletions maui/src/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System.Runtime.CompilerServices;

[assembly: InternalsVisibleTo("Syncfusion.Maui.Toolkit.UnitTest")]
[assembly: XmlnsDefinition("http://schemas.syncfusion.com/maui/toolkit", "Syncfusion.Maui.Toolkit.BottomSheet")]
[assembly: XmlnsDefinition("http://schemas.syncfusion.com/maui/toolkit", "Syncfusion.Maui.Toolkit.Calendar")]
[assembly: XmlnsDefinition("http://schemas.syncfusion.com/maui/toolkit", "Syncfusion.Maui.Toolkit.Carousel")]
[assembly: XmlnsDefinition("http://schemas.syncfusion.com/maui/toolkit", "Syncfusion.Maui.Toolkit.Charts")]
Expand Down
146 changes: 146 additions & 0 deletions maui/src/BottomSheet/BottomSheetBorder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
using Syncfusion.Maui.Toolkit.Helper;
using Syncfusion.Maui.Toolkit.Internals;

namespace Syncfusion.Maui.Toolkit.BottomSheet
{
/// <summary>
/// Represents the <see cref="BottomSheetBorder"/> that defines the layout of bottom sheet.
/// </summary>
internal class BottomSheetBorder : SfBorder, ITouchListener
{
#region Fields

// To store the weak reference of bottom sheet instance.
readonly WeakReference<SfBottomSheet>? _bottomSheetRef;

#if IOS

// To store the child count of bottom sheet
double _childLoopCount;

#endif

#endregion

#region Constructor

/// <summary>
/// Initializes a new instance of the <see cref="BottomSheetBorder"/> class.
/// </summary>
/// <param name="bottomSheet">The SfBottomSheet instance.</param>
/// <exception cref="ArgumentNullException">Thrown if bottomSheet is null.</exception>
public BottomSheetBorder(SfBottomSheet bottomSheet)
{
if (bottomSheet is not null)
{
_bottomSheetRef = new WeakReference<SfBottomSheet>(bottomSheet);
this.AddTouchListener(this);
}
}

#endregion

#region Private Methods

#if IOS
/// <summary>
/// Gets the X and Y coordinates of the specified element based on the screen.
/// </summary>
/// <param name="element">The current element for which coordinates are requested.</param>
/// <param name="touchPoint">The current element for which coordinates are requested.</param>
bool IsChildElementScrolled(IVisualTreeElement? element, Point touchPoint)
{
if (element is null)
{
return false;
}

var view = element as View;
if (view is null || view.Handler is null || view.Handler.PlatformView is null)
{
return false;
}

if (view is ScrollView || view is ListView || view is CollectionView)
{
return true;
}

foreach (var childView in element.GetVisualChildren().OfType<View>())
{
if (childView is null || childView.Handler is null || childView.Handler.PlatformView is null)
{
return false;
}

var childNativeView = childView.Handler.PlatformView;

// Here items X and Y position converts based on screen.
Point locationOnScreen = ChildLocationToScreen(childNativeView);
var bottom = locationOnScreen.Y + childView.Bounds.Height;
var right = locationOnScreen.X + childView.Bounds.Width;

// We loop through child only 10 times.
if (touchPoint.Y >= locationOnScreen.Y && touchPoint.Y <= bottom && touchPoint.X >= locationOnScreen.X && touchPoint.X <= right && _childLoopCount <= 10)
{
_childLoopCount++;
return IsChildElementScrolled(childView, touchPoint);
}
}

_childLoopCount = 0;
return false;
}

Point ChildLocationToScreen(object child)
{
if (child is UIKit.UIView view && this.Handler is not null)
{
var point = view.ConvertPointToView(view.Bounds.Location, Handler.PlatformView as UIKit.UIView);
return new Microsoft.Maui.Graphics.Point(point.X, point.Y);
}

return new Microsoft.Maui.Graphics.Point(0, 0);
}
#endif

#endregion

#region Interface Implementation

/// <summary>
/// Method to invoke swiping in bottom sheet.
/// </summary>
/// <param name="e">e.</param>
public void OnTouch(Toolkit.Internals.PointerEventArgs e)
{
#if IOS || MACCATALYST || ANDROID

#if IOS
if (Content is null)
{
return;
}

var firstDescendant = Content.GetVisualTreeDescendants().FirstOrDefault();
if (firstDescendant is not null && IsChildElementScrolled(firstDescendant, e.TouchPoint))
{
return;
}

#endif
if (e is not null && _bottomSheetRef is not null)
{
if (_bottomSheetRef.TryGetTarget(out var bottomSheet))
{
bottomSheet.OnHandleTouch(e.Action, e.TouchPoint);
}
}

#endif
}

#endregion

}
}
76 changes: 76 additions & 0 deletions maui/src/BottomSheet/Enum.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
namespace Syncfusion.Maui.Toolkit.BottomSheet
{
/// <summary>
/// Specifies the current display state of the SfBottomSheet control.
/// </summary>
/// <remarks>
/// This enum is used to represent the various possible states of the bottom sheet,
/// allowing for precise control and state management of the UI component.
/// </remarks>
public enum BottomSheetState
{
/// <summary>
/// Indicates that the bottom sheet is fully expanded to cover the entire screen.
/// </summary>
FullExpanded,

/// <summary>
/// Represents the state where the bottom sheet is expanded to cover approximately half of the screen.
/// </summary>
HalfExpanded,

/// <summary>
/// Denotes that the bottom sheet is in its minimized or collapsed state, typically showing only a small portion or header.
/// </summary>
Collapsed,

/// <summary>
/// Signifies that the bottom sheet is completely hidden from view.
/// </summary>
Hidden
}

/// <summary>
/// Defines the allowable states for the SfBottomSheet control.
/// </summary>
/// <remarks>
/// This enum is used to configure the permitted states of the bottom sheet,
/// enabling developers to restrict or allow specific display modes.
/// </remarks>
public enum BottomSheetAllowedState
{
/// <summary>
/// Configures the bottom sheet to only allow full screen expansion.
/// When set, the bottom sheet can only be fully expanded or hidden.
/// </summary>
FullExpanded,

/// <summary>
/// Restricts the bottom sheet to only permit half screen expansion.
/// When set, the bottom sheet can only be half expanded or hidden.
/// </summary>
HalfExpanded,

/// <summary>
/// Allows the bottom sheet to be displayed in both full screen and half screen modes.
/// This option provides the most flexibility, permitting all possible states.
/// </summary>
All
}

/// <summary>
/// Defines the content width mode for the SfBottomSheet control.
/// </summary>
public enum BottomSheetContentWidthMode
{
/// <summary>
/// The BottomSheet will span the full width of the parent container.
/// </summary>
Full,

/// <summary>
/// The BottomSheet will use a custom width value, centered if not full width.
/// </summary>
Custom
}
}
Loading

0 comments on commit 7cb6532

Please sign in to comment.