Created
August 24, 2020 00:21
-
-
Save mattleibow/47c18830fa5cf4ddf665567b56f16015 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections; | |
using System.Collections.Generic; | |
using System.Windows.Input; | |
using SkiaSharp.Extended.Controls; | |
using Xamarin.Forms; | |
namespace SkiaSharpDemo.Demos | |
{ | |
public partial class ConfettiPage : ContentPage | |
{ | |
public ConfettiPage() | |
{ | |
InitializeComponent(); | |
BindingContext = this; | |
} | |
private void OnTapped(object sender, EventArgs e) | |
{ | |
confettiView.Systems!.Add(new SKConfettiSystem | |
{ | |
Emitter = SKConfettiEmitter.Burst(200) | |
}); | |
} | |
} | |
internal class OptionButtonsManager | |
{ | |
// TODO: this should probably be an event... | |
private static readonly ICommand OptionTappedCommand = new Command<View>(OnOptionTapped); | |
private bool isSubscribed; | |
public void OnChildAdded(object sender, ElementEventArgs e) | |
{ | |
if (e.Element is Button button) | |
{ | |
button.Command = OptionTappedCommand; | |
button.CommandParameter = button; | |
} | |
} | |
public void OnChildRemoved(object sender, ElementEventArgs e) | |
{ | |
if (e.Element is Button button) | |
{ | |
button.Command = null; | |
button.CommandParameter = null; | |
} | |
} | |
public void UpdateChildren(Layout<View> layout) | |
{ | |
foreach (var child in layout.Children) | |
{ | |
if (child is Button button) | |
{ | |
button.Command = OptionTappedCommand; | |
button.CommandParameter = button; | |
} | |
} | |
} | |
public void Subscribe(Layout<View> layout) | |
{ | |
if (isSubscribed) | |
return; | |
layout.ChildAdded += OnChildAdded; | |
layout.ChildRemoved += OnChildRemoved; | |
isSubscribed = true; | |
} | |
private static void OnOptionTapped(View button) | |
{ | |
const string Selected = "Selected"; | |
const string Unselected = "Unselected"; | |
if (!(button?.Parent is Layout<View> parent) || !(button.BindingContext is object item)) | |
return; | |
var style = OptionButtons.GetSelectionMode(parent); | |
if (style == SelectionMode.None) | |
return; | |
var selectedItems = OptionButtons.GetSelectedItems(parent); | |
if (style != SelectionMode.Multiple) | |
{ | |
selectedItems?.Clear(); | |
foreach (var btn in parent.Children) | |
{ | |
if (btn != button) | |
VisualStateManager.GoToState(btn, Unselected); | |
} | |
} | |
var shouldSelect = false; | |
// update the selected items list | |
if (selectedItems != null) | |
{ | |
shouldSelect = !selectedItems.Contains(item); | |
if (shouldSelect) | |
selectedItems.Add(item); | |
else | |
selectedItems.Remove(item); | |
} | |
// updated the selected item | |
OptionButtons.SetSelectedItem(parent, item); | |
VisualStateManager.GoToState(button, shouldSelect ? Selected : Unselected); | |
} | |
} | |
public static class OptionButtons | |
{ | |
// OptionButtonsManager | |
private static OptionButtonsManager? GetOptionButtonsManager(BindableObject obj) => | |
(OptionButtonsManager?)obj.GetValue(OptionButtonsManagerProperty); | |
private static readonly BindableProperty OptionButtonsManagerProperty = BindableProperty.CreateAttached( | |
"OptionButtonsManager", | |
typeof(OptionButtonsManager), | |
typeof(Layout<View>), | |
null, | |
defaultValueCreator: b => new OptionButtonsManager()); | |
// SelectionMode | |
public static SelectionMode GetSelectionMode(BindableObject obj) => | |
(SelectionMode)obj.GetValue(SelectionModeProperty); | |
public static void SetSelectionMode(BindableObject obj, SelectionMode value) => | |
obj.SetValue(SelectionModeProperty, value); | |
public static readonly BindableProperty SelectionModeProperty = BindableProperty.CreateAttached( | |
"SelectionMode", | |
typeof(SelectionMode), | |
typeof(Layout<View>), | |
SelectionMode.Single, | |
propertyChanged: (b, o, n) => UpdateButtons(b)); | |
// SelectedItems | |
public static IList<object>? GetSelectedItems(BindableObject obj) => | |
(IList<object>?)obj.GetValue(SelectedItemsProperty); | |
public static void SetSelectedItems(BindableObject obj, IList<object>? value) => | |
obj.SetValue(SelectedItemsProperty, value); | |
public static readonly BindableProperty SelectedItemsProperty = BindableProperty.CreateAttached( | |
"SelectedItems", | |
typeof(IList<object>), | |
typeof(Layout<View>), | |
null, | |
defaultValueCreator: b => new List<object>()); | |
// SelectedItem | |
public static object? GetSelectedItem(BindableObject obj) => | |
obj.GetValue(SelectedItemProperty); | |
public static void SetSelectedItem(BindableObject obj, object? value) => | |
obj.SetValue(SelectedItemProperty, value); | |
public static readonly BindableProperty SelectedItemProperty = BindableProperty.CreateAttached( | |
"SelectedItem", | |
typeof(object), | |
typeof(Layout<View>), | |
null, | |
defaultBindingMode: BindingMode.TwoWay); | |
// ItemsSource | |
public static IEnumerable? GetItemsSource(BindableObject obj) => | |
(IEnumerable?)obj.GetValue(ItemsSourceProperty); | |
public static void SetItemsSource(BindableObject obj, IEnumerable? value) => | |
obj.SetValue(ItemsSourceProperty, value); | |
public static readonly BindableProperty ItemsSourceProperty = BindableProperty.CreateAttached( | |
"ItemsSource", | |
typeof(IEnumerable), | |
typeof(Layout<View>), | |
null, | |
propertyChanged: (b, o, n) => | |
{ | |
BindableLayout.SetItemsSource(b, (IEnumerable?)n); | |
UpdateButtons(b); | |
}); | |
// ItemTemplate | |
public static DataTemplate? GetItemTemplate(BindableObject obj) => | |
(DataTemplate?)obj.GetValue(ItemTemplateProperty); | |
public static void SetItemTemplate(BindableObject obj, DataTemplate? value) => | |
obj.SetValue(ItemTemplateProperty, value); | |
public static readonly BindableProperty ItemTemplateProperty = BindableProperty.CreateAttached( | |
"ItemTemplate", | |
typeof(DataTemplate), | |
typeof(Layout<View>), | |
null, | |
propertyChanged: (b, o, n) => | |
{ | |
BindableLayout.SetItemTemplate(b, (DataTemplate?)n); | |
UpdateButtons(b); | |
}); | |
// | |
private static void UpdateButtons(BindableObject b) | |
{ | |
if (b is Layout<View> layout && GetOptionButtonsManager(b) is OptionButtonsManager manager) | |
{ | |
manager.Subscribe(layout); | |
manager.UpdateChildren(layout); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment