Added AvatarView and Slider controls
This commit is contained in:
Родитель
236b2b05ed
Коммит
aafc4aa8df
|
@ -7,6 +7,9 @@ namespace AlohaKit.Gallery.ViewModels
|
|||
{
|
||||
protected override IEnumerable<SectionModel> CreateItems() => new[]
|
||||
{
|
||||
new SectionModel(typeof(AvatarView), "Avatar",
|
||||
"The Avatar control displays the initials of a person, entity, or group on top of a colored circular background."),
|
||||
|
||||
new SectionModel(typeof(LoadingView), "BusyIndicator",
|
||||
"It can be used to indicate busy status during app loading, data processing, etc."),
|
||||
|
||||
|
@ -22,6 +25,9 @@ namespace AlohaKit.Gallery.ViewModels
|
|||
new SectionModel(typeof(RatingView), "Rating",
|
||||
"Rating is a control that allows users to rate by selecting number of items from a predefined number of items."),
|
||||
|
||||
new SectionModel(typeof(SliderView), "Slider",
|
||||
"The Slider is a horizontal bar that can be manipulated by the user to select a double value from a continuous range."),
|
||||
|
||||
new SectionModel(typeof(ToggleSwitchView), "ToggleSwitch",
|
||||
"The ToggleSwitch is a horizontal toggle button that can be manipulated by the user to toggle between on and off states."),
|
||||
};
|
||||
|
|
|
@ -0,0 +1,89 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<ContentPage
|
||||
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
x:Class="AlohaKit.Gallery.AvatarView"
|
||||
xmlns:controls="clr-namespace:AlohaKit.Controls;assembly=AlohaKit"
|
||||
Title="Avatar">
|
||||
<ContentPage.Resources>
|
||||
<ResourceDictionary>
|
||||
|
||||
<Style x:Key="SettingsTextStyle" TargetType="Label">
|
||||
<Setter Property="FontSize" Value="9" />
|
||||
</Style>
|
||||
|
||||
<Style x:Key="SettingsEntryStyle" TargetType="Entry">
|
||||
<Setter Property="VerticalOptions" Value="Center" />
|
||||
<Setter Property="WidthRequest" Value="80" />
|
||||
<Setter Property="Margin" Value="6, 0" />
|
||||
</Style>
|
||||
|
||||
</ResourceDictionary>
|
||||
</ContentPage.Resources>
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
<!-- DESCRIPTION -->
|
||||
<StackLayout
|
||||
Style="{StaticResource SectionContainerStyle}">
|
||||
<Label
|
||||
Text="The Avatar control displays the initials of a person, entity, or group on top of a colored circular background."/>
|
||||
</StackLayout>
|
||||
<!-- FEATURES -->
|
||||
<StackLayout
|
||||
Grid.Row="1"
|
||||
BackgroundColor="{AppThemeBinding Light={StaticResource LightBackgroundSecondaryColor}, Dark={StaticResource DarkBackgroundSecondaryColor}}"
|
||||
Style="{StaticResource SectionContainerStyle}">
|
||||
<Label
|
||||
Text="Features"
|
||||
Style="{StaticResource SectionTitleStyle}"/>
|
||||
<Label
|
||||
Text="- Can choose from several predefined sizes."/>
|
||||
<Label
|
||||
Text="- Allow to customize the background with a gradient."/>
|
||||
<Label
|
||||
Text="- Allow to customize the fill with a gradient."/>
|
||||
</StackLayout>
|
||||
<!-- SETTINGS -->
|
||||
<StackLayout
|
||||
Grid.Row="2"
|
||||
Style="{StaticResource SectionContainerStyle}">
|
||||
<Label
|
||||
Text="Settings"
|
||||
Style="{StaticResource SectionTitleStyle}"/>
|
||||
<StackLayout
|
||||
Orientation="Horizontal"
|
||||
Margin="0, 6">
|
||||
<Label
|
||||
Text="Fill Start Color"
|
||||
VerticalOptions="Center"
|
||||
Style="{StaticResource SettingsTextStyle}"/>
|
||||
<Entry
|
||||
x:Name="FillStartColorEntry"
|
||||
Placeholder="Background Color"
|
||||
Text="#DD5E89"
|
||||
TextChanged="OnFillStartColorEntryTextChanged"
|
||||
Style="{StaticResource SettingsEntryStyle}"/>
|
||||
<Label
|
||||
Text="Fill End Color"
|
||||
VerticalOptions="Center"
|
||||
Style="{StaticResource SettingsTextStyle}"/>
|
||||
<Entry
|
||||
x:Name="FillEndColorEntry"
|
||||
Placeholder="Color"
|
||||
Text="#F7BB97"
|
||||
TextChanged="OnFillEndColorEntryTextChanged"
|
||||
Style="{StaticResource SettingsEntryStyle}"/>
|
||||
</StackLayout>
|
||||
</StackLayout>
|
||||
<controls:Avatar
|
||||
Grid.Row="3"
|
||||
x:Name="Avatar"
|
||||
HorizontalOptions="Center"
|
||||
Name="Javier Suarez"/>
|
||||
</Grid>
|
||||
</ContentPage>
|
|
@ -0,0 +1,59 @@
|
|||
namespace AlohaKit.Gallery;
|
||||
|
||||
public partial class AvatarView : ContentPage
|
||||
{
|
||||
public AvatarView()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
UpdateBrushes();
|
||||
}
|
||||
|
||||
void OnFillStartColorEntryTextChanged(object sender, TextChangedEventArgs e)
|
||||
{
|
||||
UpdateBrushes();
|
||||
}
|
||||
|
||||
void OnFillEndColorEntryTextChanged(object sender, TextChangedEventArgs e)
|
||||
{
|
||||
UpdateBrushes();
|
||||
}
|
||||
|
||||
void UpdateBrushes()
|
||||
{
|
||||
var fillStartColor = GetColorFromString(FillStartColorEntry.Text);
|
||||
var fillEndColor = GetColorFromString(FillEndColorEntry.Text);
|
||||
|
||||
if (fillStartColor != null && fillEndColor != null)
|
||||
{
|
||||
FillStartColorEntry.BackgroundColor = fillStartColor;
|
||||
FillEndColorEntry.BackgroundColor = fillEndColor;
|
||||
|
||||
Avatar.Fill = new LinearGradientBrush
|
||||
{
|
||||
StartPoint = new Point(0, 0),
|
||||
EndPoint = new Point(1, 0),
|
||||
GradientStops = new GradientStopCollection
|
||||
{
|
||||
new GradientStop { Color = fillStartColor, Offset = 0 },
|
||||
new GradientStop { Color = fillEndColor, Offset = 1 }
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Color GetColorFromString(string value)
|
||||
{
|
||||
if (string.IsNullOrEmpty(value))
|
||||
return null;
|
||||
|
||||
try
|
||||
{
|
||||
return Color.FromArgb(value[0].Equals('#') ? value : $"#{value}");
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,131 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<ContentPage
|
||||
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
x:Class="AlohaKit.Gallery.SliderView"
|
||||
xmlns:controls="clr-namespace:AlohaKit.Controls;assembly=AlohaKit"
|
||||
Title="Slider">
|
||||
<ContentPage.Resources>
|
||||
<ResourceDictionary>
|
||||
|
||||
<Style x:Key="SettingsTextStyle" TargetType="Label">
|
||||
<Setter Property="FontSize" Value="9" />
|
||||
</Style>
|
||||
|
||||
<Style x:Key="SettingsEntryStyle" TargetType="Entry">
|
||||
<Setter Property="VerticalOptions" Value="Center" />
|
||||
<Setter Property="WidthRequest" Value="80" />
|
||||
<Setter Property="Margin" Value="6, 0" />
|
||||
</Style>
|
||||
|
||||
</ResourceDictionary>
|
||||
</ContentPage.Resources>
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
<!-- DESCRIPTION -->
|
||||
<StackLayout
|
||||
Style="{StaticResource SectionContainerStyle}">
|
||||
<Label
|
||||
Text="Slider is a horizontal bar that can be manipulated by the user to select a double value from a continuous range."/>
|
||||
</StackLayout>
|
||||
<!-- FEATURES -->
|
||||
<StackLayout
|
||||
Grid.Row="1"
|
||||
BackgroundColor="{AppThemeBinding Light={StaticResource LightBackgroundSecondaryColor}, Dark={StaticResource DarkBackgroundSecondaryColor}}"
|
||||
Style="{StaticResource SectionContainerStyle}">
|
||||
<Label
|
||||
Text="Features"
|
||||
Style="{StaticResource SectionTitleStyle}"/>
|
||||
<Label
|
||||
Text="- All the colors can be customized supporting gradients."/>
|
||||
</StackLayout>
|
||||
<!-- SETTINGS -->
|
||||
<StackLayout
|
||||
Grid.Row="2"
|
||||
Style="{StaticResource SectionContainerStyle}">
|
||||
<Label
|
||||
Text="Settings"
|
||||
Style="{StaticResource SectionTitleStyle}"/>
|
||||
<StackLayout
|
||||
Orientation="Horizontal"
|
||||
Margin="0, 6">
|
||||
<Label
|
||||
Text="MinimumBrush Start Color"
|
||||
VerticalOptions="Center"
|
||||
Style="{StaticResource SettingsTextStyle}"/>
|
||||
<Entry
|
||||
x:Name="MinimumBrushStartColorEntry"
|
||||
Placeholder="MinimumBrush"
|
||||
Text="#DD5E89"
|
||||
TextChanged="OnMinimumBrushStartColorEntryTextChanged"
|
||||
Style="{StaticResource SettingsEntryStyle}"/>
|
||||
<Label
|
||||
Text="MinimumBrush End Color"
|
||||
VerticalOptions="Center"
|
||||
Style="{StaticResource SettingsTextStyle}"/>
|
||||
<Entry
|
||||
x:Name="MinimumBrushEndColorEntry"
|
||||
Placeholder="MinimumBrush"
|
||||
Text="#F7BB97"
|
||||
TextChanged="OnMinimumBrushEndColorEntryTextChanged"
|
||||
Style="{StaticResource SettingsEntryStyle}"/>
|
||||
</StackLayout>
|
||||
<StackLayout
|
||||
Orientation="Horizontal"
|
||||
Margin="0, 6">
|
||||
<Label
|
||||
Text="MaximumBrush Start Color"
|
||||
VerticalOptions="Center"
|
||||
Style="{StaticResource SettingsTextStyle}"/>
|
||||
<Entry
|
||||
x:Name="MaximumBrushStartColorEntry"
|
||||
Placeholder="MaximumBrush"
|
||||
Text="#CC2B5E"
|
||||
TextChanged="OnMaximumBrushStartColorEntryTextChanged"
|
||||
Style="{StaticResource SettingsEntryStyle}"/>
|
||||
<Label
|
||||
Text="MaximumBrush End Color"
|
||||
VerticalOptions="Center"
|
||||
Style="{StaticResource SettingsTextStyle}"/>
|
||||
<Entry
|
||||
x:Name="MaximumBrushEndColorEntry"
|
||||
Placeholder="Color"
|
||||
Text="#753A88"
|
||||
TextChanged="OnMaximumBrushEndColorEntryTextChanged"
|
||||
Style="{StaticResource SettingsEntryStyle}"/>
|
||||
</StackLayout>
|
||||
<StackLayout
|
||||
Orientation="Horizontal"
|
||||
Margin="0, 6">
|
||||
<Label
|
||||
Text="ThumbBrush Start Color"
|
||||
VerticalOptions="Center"
|
||||
Style="{StaticResource SettingsTextStyle}"/>
|
||||
<Entry
|
||||
x:Name="ThumbBrushStartColorEntry"
|
||||
Placeholder="ThumbBrush"
|
||||
Text="#CCCCCC"
|
||||
TextChanged="OnThumbBrushStartColorEntryTextChanged"
|
||||
Style="{StaticResource SettingsEntryStyle}"/>
|
||||
<Label
|
||||
Text="ThumbBrush End Color"
|
||||
VerticalOptions="Center"
|
||||
Style="{StaticResource SettingsTextStyle}"/>
|
||||
<Entry
|
||||
x:Name="ThumbBrushEndColorEntry"
|
||||
Placeholder="ThumbBrush"
|
||||
Text="#BDC3C7"
|
||||
TextChanged="OnThumbBrushEndColorEntryTextChanged"
|
||||
Style="{StaticResource SettingsEntryStyle}"/>
|
||||
</StackLayout>
|
||||
</StackLayout>
|
||||
<controls:Slider
|
||||
Grid.Row="3"
|
||||
x:Name="Slider" />
|
||||
</Grid>
|
||||
</ContentPage>
|
|
@ -0,0 +1,119 @@
|
|||
namespace AlohaKit.Gallery;
|
||||
|
||||
public partial class SliderView : ContentPage
|
||||
{
|
||||
public SliderView()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
UpdateBrushes();
|
||||
}
|
||||
|
||||
void OnMinimumBrushStartColorEntryTextChanged(object sender, TextChangedEventArgs e)
|
||||
{
|
||||
UpdateBrushes();
|
||||
}
|
||||
|
||||
void OnMinimumBrushEndColorEntryTextChanged(object sender, TextChangedEventArgs e)
|
||||
{
|
||||
UpdateBrushes();
|
||||
}
|
||||
|
||||
void OnMaximumBrushStartColorEntryTextChanged(object sender, TextChangedEventArgs e)
|
||||
{
|
||||
UpdateBrushes();
|
||||
}
|
||||
|
||||
void OnMaximumBrushEndColorEntryTextChanged(object sender, TextChangedEventArgs e)
|
||||
{
|
||||
UpdateBrushes();
|
||||
}
|
||||
|
||||
void OnThumbBrushStartColorEntryTextChanged(object sender, TextChangedEventArgs e)
|
||||
{
|
||||
UpdateBrushes();
|
||||
}
|
||||
|
||||
void OnThumbBrushEndColorEntryTextChanged(object sender, TextChangedEventArgs e)
|
||||
{
|
||||
UpdateBrushes();
|
||||
}
|
||||
|
||||
void UpdateBrushes()
|
||||
{
|
||||
var minimumStartColor = GetColorFromString(MinimumBrushStartColorEntry.Text);
|
||||
var minimumEndColor = GetColorFromString(MinimumBrushEndColorEntry.Text);
|
||||
|
||||
if (minimumStartColor != null && minimumEndColor != null)
|
||||
{
|
||||
MinimumBrushStartColorEntry.BackgroundColor = minimumStartColor;
|
||||
MinimumBrushEndColorEntry.BackgroundColor = minimumEndColor;
|
||||
|
||||
Slider.MinimumBrush = new LinearGradientBrush
|
||||
{
|
||||
StartPoint = new Point(0, 0),
|
||||
EndPoint = new Point(1, 0),
|
||||
GradientStops = new GradientStopCollection
|
||||
{
|
||||
new GradientStop { Color = minimumStartColor, Offset = 0 },
|
||||
new GradientStop { Color = minimumEndColor, Offset = 1 }
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
var maximumStartColor = GetColorFromString(MaximumBrushStartColorEntry.Text);
|
||||
var maximumEndColor = GetColorFromString(MaximumBrushEndColorEntry.Text);
|
||||
|
||||
if (maximumStartColor != null && maximumEndColor != null)
|
||||
{
|
||||
MaximumBrushStartColorEntry.BackgroundColor = maximumStartColor;
|
||||
MaximumBrushEndColorEntry.BackgroundColor = maximumEndColor;
|
||||
|
||||
Slider.MaximumBrush = new LinearGradientBrush
|
||||
{
|
||||
StartPoint = new Point(0, 0),
|
||||
EndPoint = new Point(1, 0),
|
||||
GradientStops = new GradientStopCollection
|
||||
{
|
||||
new GradientStop { Color = maximumStartColor, Offset = 0 },
|
||||
new GradientStop { Color = maximumEndColor, Offset = 1 }
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
var thumbStartColor = GetColorFromString(ThumbBrushStartColorEntry.Text);
|
||||
var thumbEndColor = GetColorFromString(ThumbBrushEndColorEntry.Text);
|
||||
|
||||
if (thumbStartColor != null && thumbEndColor != null)
|
||||
{
|
||||
ThumbBrushStartColorEntry.BackgroundColor = thumbStartColor;
|
||||
ThumbBrushEndColorEntry.BackgroundColor = thumbEndColor;
|
||||
|
||||
Slider.ThumbBrush = new LinearGradientBrush
|
||||
{
|
||||
StartPoint = new Point(0, 0),
|
||||
EndPoint = new Point(1, 0),
|
||||
GradientStops = new GradientStopCollection
|
||||
{
|
||||
new GradientStop { Color = thumbStartColor, Offset = 0 },
|
||||
new GradientStop { Color = thumbEndColor, Offset = 1 }
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Color GetColorFromString(string value)
|
||||
{
|
||||
if (string.IsNullOrEmpty(value))
|
||||
return null;
|
||||
|
||||
try
|
||||
{
|
||||
return Color.FromArgb(value[0].Equals('#') ? value : $"#{value}");
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,172 @@
|
|||
namespace AlohaKit.Controls
|
||||
{
|
||||
public class Avatar : GraphicsView
|
||||
{
|
||||
public Avatar()
|
||||
{
|
||||
Drawable = PersonaDrawable = new AvatarDrawable();
|
||||
}
|
||||
|
||||
public AvatarDrawable PersonaDrawable { get; set; }
|
||||
|
||||
public static readonly new BindableProperty BackgroundProperty =
|
||||
BindableProperty.Create(nameof(Background), typeof(Brush), typeof(Avatar), null,
|
||||
propertyChanged: (bindableObject, oldValue, newValue) =>
|
||||
{
|
||||
if (newValue != null && bindableObject is Avatar avatar)
|
||||
{
|
||||
avatar.UpdateBackground();
|
||||
}
|
||||
});
|
||||
|
||||
public new Brush Background
|
||||
{
|
||||
get => (Brush)GetValue(BackgroundProperty);
|
||||
set => SetValue(BackgroundProperty, value);
|
||||
}
|
||||
|
||||
public static readonly BindableProperty FillProperty =
|
||||
BindableProperty.Create(nameof(Fill), typeof(Brush), typeof(Avatar), new SolidColorBrush(Color.FromArgb("#4967F5")),
|
||||
propertyChanged: (bindableObject, oldValue, newValue) =>
|
||||
{
|
||||
if (newValue != null && bindableObject is Avatar avatar)
|
||||
{
|
||||
avatar.UpdateFill();
|
||||
}
|
||||
});
|
||||
|
||||
public Brush Fill
|
||||
{
|
||||
get => (Brush)GetValue(FillProperty);
|
||||
set => SetValue(FillProperty, value);
|
||||
}
|
||||
|
||||
public static readonly BindableProperty NameProperty =
|
||||
BindableProperty.Create(nameof(Name), typeof(string), typeof(Avatar), string.Empty,
|
||||
propertyChanged: (bindableObject, oldValue, newValue) =>
|
||||
{
|
||||
if (newValue != null && bindableObject is Avatar avatar)
|
||||
{
|
||||
avatar.UpdateName();
|
||||
}
|
||||
});
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return (string)GetValue(NameProperty); }
|
||||
set { SetValue(NameProperty, value); }
|
||||
}
|
||||
|
||||
public static readonly BindableProperty TextColorProperty =
|
||||
BindableProperty.Create(nameof(TextColor), typeof(Color), typeof(Avatar), Colors.White,
|
||||
propertyChanged: (bindableObject, oldValue, newValue) =>
|
||||
{
|
||||
if (newValue != null && bindableObject is Avatar avatar)
|
||||
{
|
||||
avatar.UpdateTextColor();
|
||||
}
|
||||
});
|
||||
|
||||
public Color TextColor
|
||||
{
|
||||
get { return (Color)GetValue(TextColorProperty); }
|
||||
set { SetValue(TextColorProperty, value); }
|
||||
}
|
||||
|
||||
public static readonly BindableProperty AvatarSizeProperty =
|
||||
BindableProperty.Create(nameof(AvatarSize), typeof(AvatarSize), typeof(Avatar), AvatarSize.Small,
|
||||
propertyChanged: (bindableObject, oldValue, newValue) =>
|
||||
{
|
||||
if (newValue != null && bindableObject is Avatar avatar)
|
||||
{
|
||||
avatar.UpdateAvatarSize();
|
||||
}
|
||||
});
|
||||
|
||||
public AvatarSize AvatarSize
|
||||
{
|
||||
get { return (AvatarSize)GetValue(AvatarSizeProperty); }
|
||||
set { SetValue(AvatarSizeProperty, value); }
|
||||
}
|
||||
|
||||
protected override void OnParentSet()
|
||||
{
|
||||
base.OnParentSet();
|
||||
|
||||
if (Parent != null)
|
||||
{
|
||||
UpdateAvatarSize();
|
||||
UpdateBackground();
|
||||
UpdateFill();
|
||||
UpdateName();
|
||||
UpdateTextColor();
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAvatarSize()
|
||||
{
|
||||
HeightRequest = WidthRequest = AvatarSize.GetAvatarSize();
|
||||
}
|
||||
|
||||
void UpdateBackground()
|
||||
{
|
||||
if (PersonaDrawable == null)
|
||||
return;
|
||||
|
||||
PersonaDrawable.BackgroundPaint = Background;
|
||||
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
void UpdateFill()
|
||||
{
|
||||
if (PersonaDrawable == null)
|
||||
return;
|
||||
|
||||
PersonaDrawable.FillPaint = Fill;
|
||||
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
void UpdateName()
|
||||
{
|
||||
if (PersonaDrawable == null)
|
||||
return;
|
||||
|
||||
PersonaDrawable.Text = GetInitials(Name);
|
||||
PersonaDrawable.FontSize = AvatarSize.GetInitialsFontSize();
|
||||
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
void UpdateTextColor()
|
||||
{
|
||||
if (PersonaDrawable == null)
|
||||
return;
|
||||
|
||||
PersonaDrawable.TextColor = TextColor;
|
||||
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
string GetInitials(string text)
|
||||
{
|
||||
string result = string.Empty;
|
||||
|
||||
bool v = true;
|
||||
|
||||
for (int i = 0; i < text.Length; i++)
|
||||
{
|
||||
if (text[i] == ' ')
|
||||
v = true;
|
||||
else if (text[i] != ' ' && v)
|
||||
{
|
||||
result += text[i];
|
||||
v = false;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
namespace AlohaKit.Controls
|
||||
{
|
||||
public class AvatarDrawable : IDrawable
|
||||
{
|
||||
public Paint BackgroundPaint { get; set; }
|
||||
public Paint FillPaint { get; set; }
|
||||
public string Text { get; set; }
|
||||
public Color TextColor { get; set; }
|
||||
public double FontSize { get; set; }
|
||||
|
||||
public void Draw(ICanvas canvas, RectF dirtyRect)
|
||||
{
|
||||
DrawBackground(canvas, dirtyRect);
|
||||
DrawFill(canvas, dirtyRect);
|
||||
DrawInitials(canvas, dirtyRect);
|
||||
}
|
||||
|
||||
public virtual void DrawBackground(ICanvas canvas, RectF dirtyRect)
|
||||
{
|
||||
canvas.SaveState();
|
||||
|
||||
if (BackgroundPaint != null)
|
||||
canvas.SetFillPaint(BackgroundPaint, dirtyRect);
|
||||
|
||||
canvas.FillRectangle(dirtyRect);
|
||||
|
||||
canvas.RestoreState();
|
||||
}
|
||||
|
||||
public virtual void DrawFill(ICanvas canvas, RectF dirtyRect)
|
||||
{
|
||||
canvas.SaveState();
|
||||
|
||||
if (FillPaint != null)
|
||||
canvas.SetFillPaint(FillPaint, dirtyRect);
|
||||
|
||||
var x = dirtyRect.X;
|
||||
var y = dirtyRect.Y;
|
||||
|
||||
var height = dirtyRect.Height;
|
||||
var width = dirtyRect.Width;
|
||||
|
||||
canvas.FillEllipse(x, y, width, height);
|
||||
|
||||
canvas.RestoreState();
|
||||
}
|
||||
|
||||
void DrawInitials(ICanvas canvas, RectF dirtyRect)
|
||||
{
|
||||
canvas.SaveState();
|
||||
|
||||
canvas.FontColor = TextColor;
|
||||
|
||||
canvas.FontSize = (float)FontSize;
|
||||
|
||||
var height = dirtyRect.Height;
|
||||
var width = dirtyRect.Width;
|
||||
|
||||
canvas.DrawString(Text, 0, 0, width, height, HorizontalAlignment.Center, VerticalAlignment.Center);
|
||||
|
||||
canvas.RestoreState();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
namespace AlohaKit.Controls
|
||||
{
|
||||
public enum AvatarSize
|
||||
{
|
||||
Small,
|
||||
Large,
|
||||
XXLarge
|
||||
}
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
namespace AlohaKit.Controls
|
||||
{
|
||||
public static class AvatarSizeExtensions
|
||||
{
|
||||
public static int GetAvatarSize(this AvatarSize avatarSize)
|
||||
{
|
||||
switch (avatarSize)
|
||||
{
|
||||
case AvatarSize.Small:
|
||||
default:
|
||||
return 48;
|
||||
case AvatarSize.Large:
|
||||
return 72;
|
||||
case AvatarSize.XXLarge:
|
||||
return 120;
|
||||
}
|
||||
}
|
||||
|
||||
public static int GetAvatarIndicatorSize(this AvatarSize avatarSize)
|
||||
{
|
||||
switch (avatarSize)
|
||||
{
|
||||
case AvatarSize.Small:
|
||||
default:
|
||||
return 12;
|
||||
case AvatarSize.Large:
|
||||
return 20;
|
||||
case AvatarSize.XXLarge:
|
||||
return 36;
|
||||
}
|
||||
}
|
||||
|
||||
public static float GetAvatarIndicatorIconScale(this AvatarSize avatarSize)
|
||||
{
|
||||
switch (avatarSize)
|
||||
{
|
||||
case AvatarSize.Small:
|
||||
default:
|
||||
return 1.0f;
|
||||
case AvatarSize.Large:
|
||||
return 1.5f;
|
||||
case AvatarSize.XXLarge:
|
||||
return 2.5f;
|
||||
}
|
||||
}
|
||||
|
||||
public static int GetInitialsFontSize(this AvatarSize avatarSize)
|
||||
{
|
||||
switch (avatarSize)
|
||||
{
|
||||
case AvatarSize.Small:
|
||||
default:
|
||||
return 20;
|
||||
case AvatarSize.Large:
|
||||
return 28;
|
||||
case AvatarSize.XXLarge:
|
||||
return 42;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -23,7 +23,7 @@
|
|||
DrawRatingItem(canvas, dirtyRect, i);
|
||||
}
|
||||
}
|
||||
void DrawBackground(ICanvas canvas, RectF dirtyRect)
|
||||
public virtual void DrawBackground(ICanvas canvas, RectF dirtyRect)
|
||||
{
|
||||
canvas.SaveState();
|
||||
|
||||
|
@ -35,7 +35,7 @@
|
|||
canvas.RestoreState();
|
||||
}
|
||||
|
||||
void DrawRatingItem(ICanvas canvas, RectF dirtyRect, int index)
|
||||
public virtual void DrawRatingItem(ICanvas canvas, RectF dirtyRect, int index)
|
||||
{
|
||||
canvas.SaveState();
|
||||
|
||||
|
|
|
@ -0,0 +1,236 @@
|
|||
namespace AlohaKit.Controls
|
||||
{
|
||||
public class Slider : GraphicsView
|
||||
{
|
||||
public Slider()
|
||||
{
|
||||
HeightRequest = 20;
|
||||
WidthRequest = 120;
|
||||
|
||||
Drawable = SliderDrawable = new SliderDrawable();
|
||||
|
||||
StartInteraction += OnSliderStartInteraction;
|
||||
DragInteraction += OnSliderDragInteraction;
|
||||
}
|
||||
|
||||
public SliderDrawable SliderDrawable { get; set; }
|
||||
|
||||
public static readonly new BindableProperty BackgroundProperty =
|
||||
BindableProperty.Create(nameof(Background), typeof(Brush), typeof(Button), null,
|
||||
propertyChanged: (bindableObject, oldValue, newValue) =>
|
||||
{
|
||||
if (newValue != null && bindableObject is Slider slider)
|
||||
{
|
||||
slider.UpdateBackground();
|
||||
}
|
||||
});
|
||||
|
||||
public new Brush Background
|
||||
{
|
||||
get => (Brush)GetValue(BackgroundProperty);
|
||||
set => SetValue(BackgroundProperty, value);
|
||||
}
|
||||
|
||||
public static readonly BindableProperty MinimumProperty =
|
||||
BindableProperty.Create(nameof(Minimum), typeof(double), typeof(Slider), 0d,
|
||||
propertyChanged: (bindableObject, oldValue, newValue) =>
|
||||
{
|
||||
if (newValue != null && bindableObject is Slider slider)
|
||||
{
|
||||
slider.UpdateMinimum();
|
||||
}
|
||||
});
|
||||
|
||||
public double Minimum
|
||||
{
|
||||
get => (double)GetValue(MinimumProperty);
|
||||
set => SetValue(MinimumProperty, value);
|
||||
}
|
||||
|
||||
public static readonly BindableProperty MaximumProperty =
|
||||
BindableProperty.Create(nameof(Maximum), typeof(double), typeof(Slider), 10d,
|
||||
propertyChanged: (bindableObject, oldValue, newValue) =>
|
||||
{
|
||||
if (newValue != null && bindableObject is Slider slider)
|
||||
{
|
||||
slider.UpdateMaximum();
|
||||
}
|
||||
});
|
||||
|
||||
public double Maximum
|
||||
{
|
||||
get => (double)GetValue(MaximumProperty);
|
||||
set => SetValue(MaximumProperty, value);
|
||||
}
|
||||
|
||||
public static readonly BindableProperty ValueProperty =
|
||||
BindableProperty.Create(nameof(Value), typeof(double), typeof(Slider), 0d,
|
||||
propertyChanged: (bindableObject, oldValue, newValue) =>
|
||||
{
|
||||
if (newValue != null && bindableObject is Slider slider)
|
||||
{
|
||||
slider.UpdateValue();
|
||||
slider.ValueChanged?.Invoke(slider, new ValueChangedEventArgs((double)oldValue, (double)newValue));
|
||||
}
|
||||
});
|
||||
|
||||
public double Value
|
||||
{
|
||||
get => (double)GetValue(ValueProperty);
|
||||
set => SetValue(ValueProperty, value);
|
||||
}
|
||||
|
||||
public static readonly BindableProperty MinimumBrushProperty =
|
||||
BindableProperty.Create(nameof(MinimumBrush), typeof(Brush), typeof(Slider), null,
|
||||
propertyChanged: (bindableObject, oldValue, newValue) =>
|
||||
{
|
||||
if (newValue != null && bindableObject is Slider slider)
|
||||
{
|
||||
slider.UpdateMinimumBrush();
|
||||
}
|
||||
});
|
||||
|
||||
public Brush MinimumBrush
|
||||
{
|
||||
get => (Brush)GetValue(MinimumBrushProperty);
|
||||
set => SetValue(MinimumBrushProperty, value);
|
||||
}
|
||||
|
||||
public static readonly BindableProperty MaximumBrushProperty =
|
||||
BindableProperty.Create(nameof(MaximumBrush), typeof(Brush), typeof(Slider), null,
|
||||
propertyChanged: (bindableObject, oldValue, newValue) =>
|
||||
{
|
||||
if (newValue != null && bindableObject is Slider slider)
|
||||
{
|
||||
slider.UpdateMaximumBrush();
|
||||
}
|
||||
});
|
||||
|
||||
public Brush MaximumBrush
|
||||
{
|
||||
get => (Brush)GetValue(MaximumBrushProperty);
|
||||
set => SetValue(MaximumBrushProperty, value);
|
||||
}
|
||||
|
||||
public static readonly BindableProperty ThumbBrushProperty =
|
||||
BindableProperty.Create(nameof(ThumbBrush), typeof(Brush), typeof(Slider), null,
|
||||
propertyChanged: (bindableObject, oldValue, newValue) =>
|
||||
{
|
||||
if (newValue != null && bindableObject is Slider slider)
|
||||
{
|
||||
slider.UpdateThumbBrush();
|
||||
}
|
||||
});
|
||||
|
||||
public Brush ThumbBrush
|
||||
{
|
||||
get => (Brush)GetValue(ThumbBrushProperty);
|
||||
set => SetValue(ThumbBrushProperty, value);
|
||||
}
|
||||
|
||||
public event EventHandler<ValueChangedEventArgs> ValueChanged;
|
||||
|
||||
protected override void OnParentSet()
|
||||
{
|
||||
base.OnParentSet();
|
||||
|
||||
if(Parent != null)
|
||||
{
|
||||
UpdateBackground();
|
||||
UpdateMinimum();
|
||||
UpdateMaximum();
|
||||
UpdateValue();
|
||||
UpdateMinimumBrush();
|
||||
UpdateMaximumBrush();
|
||||
UpdateThumbBrush();
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateBackground()
|
||||
{
|
||||
if (SliderDrawable == null)
|
||||
return;
|
||||
|
||||
SliderDrawable.BackgroundPaint = Background;
|
||||
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
void UpdateMinimum()
|
||||
{
|
||||
if (SliderDrawable == null)
|
||||
return;
|
||||
|
||||
SliderDrawable.Minimum = Minimum;
|
||||
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
void UpdateMaximum()
|
||||
{
|
||||
if (SliderDrawable == null)
|
||||
return;
|
||||
|
||||
SliderDrawable.Maximum = Maximum;
|
||||
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
void UpdateValue()
|
||||
{
|
||||
if (SliderDrawable == null)
|
||||
return;
|
||||
|
||||
SliderDrawable.Value = Value;
|
||||
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
void UpdateMinimumBrush()
|
||||
{
|
||||
if (SliderDrawable == null)
|
||||
return;
|
||||
|
||||
SliderDrawable.MinimumPaint = MinimumBrush;
|
||||
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
void UpdateMaximumBrush()
|
||||
{
|
||||
if (SliderDrawable == null)
|
||||
return;
|
||||
|
||||
SliderDrawable.MaximumPaint = MaximumBrush;
|
||||
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
void UpdateThumbBrush()
|
||||
{
|
||||
if (SliderDrawable == null)
|
||||
return;
|
||||
|
||||
SliderDrawable.ThumbPaint = ThumbBrush;
|
||||
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
void OnSliderStartInteraction(object sender, TouchEventArgs args)
|
||||
{
|
||||
var touchPoint = args.Touches[0];
|
||||
UpdateValueFromInteraction(touchPoint);
|
||||
}
|
||||
|
||||
void OnSliderDragInteraction(object sender, TouchEventArgs args)
|
||||
{
|
||||
var touchPoint = args.Touches[0];
|
||||
UpdateValueFromInteraction(touchPoint);
|
||||
}
|
||||
|
||||
void UpdateValueFromInteraction(PointF touchPoint)
|
||||
{
|
||||
Value = touchPoint.X * Maximum / Width;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,102 @@
|
|||
using AlohaKit.Extensions;
|
||||
|
||||
namespace AlohaKit.Controls
|
||||
{
|
||||
public class SliderDrawable : IDrawable
|
||||
{
|
||||
public Paint BackgroundPaint { get; set; }
|
||||
public double Minimum { get; set; }
|
||||
public double Maximum { get; set; }
|
||||
public double Value { get; set; }
|
||||
public Paint MinimumPaint { get; set; }
|
||||
public Paint MaximumPaint { get; set; }
|
||||
public Paint ThumbPaint { get; set; }
|
||||
|
||||
public void Draw(ICanvas canvas, RectF dirtyRect)
|
||||
{
|
||||
DrawBackground(canvas, dirtyRect);
|
||||
DrawTrackBackground(canvas, dirtyRect);
|
||||
DrawTrackProgress(canvas, dirtyRect);
|
||||
DrawThumb(canvas, dirtyRect);
|
||||
}
|
||||
|
||||
public virtual void DrawBackground(ICanvas canvas, RectF dirtyRect)
|
||||
{
|
||||
canvas.SaveState();
|
||||
|
||||
if (BackgroundPaint != null)
|
||||
canvas.SetFillPaint(BackgroundPaint, dirtyRect);
|
||||
|
||||
canvas.FillRectangle(dirtyRect);
|
||||
|
||||
canvas.RestoreState();
|
||||
}
|
||||
|
||||
public virtual void DrawTrackBackground(ICanvas canvas, RectF dirtyRect)
|
||||
{
|
||||
canvas.SaveState();
|
||||
|
||||
if(MaximumPaint != null)
|
||||
canvas.SetFillPaint(MaximumPaint, dirtyRect);
|
||||
|
||||
var x = dirtyRect.X;
|
||||
|
||||
var width = dirtyRect.Width;
|
||||
var height = 2;
|
||||
|
||||
var y = (float)((dirtyRect.Height - height) / 2);
|
||||
|
||||
canvas.FillRoundedRectangle(x, y, width, height, 0);
|
||||
|
||||
canvas.RestoreState();
|
||||
}
|
||||
|
||||
public virtual void DrawTrackProgress(ICanvas canvas, RectF dirtyRect)
|
||||
{
|
||||
canvas.SaveState();
|
||||
|
||||
if (MinimumPaint != null)
|
||||
canvas.SetFillPaint(MinimumPaint, dirtyRect);
|
||||
|
||||
var x = dirtyRect.X;
|
||||
|
||||
var value = (Value / Maximum - Minimum).Clamp(0, 1);
|
||||
var width = (float)(dirtyRect.Width * value);
|
||||
|
||||
const float TrackSize = 2f;
|
||||
|
||||
var height = TrackSize;
|
||||
|
||||
var y = (float)((dirtyRect.Height - height) / 2);
|
||||
|
||||
canvas.FillRoundedRectangle(x, y, width, height, 0);
|
||||
|
||||
canvas.RestoreState();
|
||||
}
|
||||
|
||||
public virtual void DrawThumb(ICanvas canvas, RectF dirtyRect)
|
||||
{
|
||||
const float ThumbSize = 18f;
|
||||
|
||||
canvas.SaveState();
|
||||
|
||||
var value = (Value / Maximum - Minimum).Clamp(0, 1);
|
||||
var x = (float)((dirtyRect.Width * value) - (ThumbSize / 2));
|
||||
|
||||
if (x <= 0)
|
||||
x = 0;
|
||||
|
||||
if (x >= dirtyRect.Width - ThumbSize)
|
||||
x = dirtyRect.Width - ThumbSize;
|
||||
|
||||
var y = (float)((dirtyRect.Height - ThumbSize) / 2);
|
||||
|
||||
if (ThumbPaint != null)
|
||||
canvas.SetFillPaint(ThumbPaint, dirtyRect);
|
||||
|
||||
canvas.FillEllipse(x, y, ThumbSize, ThumbSize);
|
||||
|
||||
canvas.RestoreState();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
namespace AlohaKit.Extensions
|
||||
{
|
||||
public static class NumericExtensions
|
||||
{
|
||||
public static double Clamp(this double self, double min, double max)
|
||||
{
|
||||
if (max < min)
|
||||
{
|
||||
return max;
|
||||
}
|
||||
else if (self < min)
|
||||
{
|
||||
return min;
|
||||
}
|
||||
else if (self > max)
|
||||
{
|
||||
return max;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче