Skip to content
This repository has been archived by the owner on May 1, 2024. It is now read-only.

Commit

Permalink
Image Button Implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
PureWeen committed Feb 28, 2018
1 parent 051700f commit eecce11
Show file tree
Hide file tree
Showing 69 changed files with 4,327 additions and 760 deletions.
8 changes: 8 additions & 0 deletions Stubs/Xamarin.Forms.Platform.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,14 @@ internal class _ImageRenderer { }
[RenderWith (typeof (ButtonRenderer))]
internal class _ButtonRenderer { }

#if __ANDROID__
[RenderWith(typeof(Android.FastRenderers.ImageButtonRenderer))]
#else
[RenderWith(typeof(ImageButtonRenderer))]
#endif
internal class _ImageButtonRenderer { }


[RenderWith (typeof (TableViewRenderer))]
internal class _TableViewRenderer { }

Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -131,11 +131,13 @@
<Compile Include="_60122ImageRenderer.cs" />
<Content Include="Assets\Fonts\OFL.txt" />
<Content Include="bank.png" />
<Content Include="calculator.png" />
<Content Include="coffee.png" />
<Content Include="cover1.jpg" />
<Content Include="cover1small.jpg" />
<Content Include="crimsonsmall.jpg" />
<Content Include="default.css" />
<Content Include="Fruits.jpg" />
<Content Include="invalidimage.jpg" />
<Content Include="local.html" />
<Content Include="test.jpg" />
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
25 changes: 25 additions & 0 deletions Xamarin.Forms.Core/BindableValueChangedEventArgs.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace Xamarin.Forms
{
public class BindableValueChangedEventArgs : EventArgs
{
public BindableValueChangedEventArgs()
{

}

public BindableValueChangedEventArgs(object owner, object oldValue, object newValue)
{
Owner = owner;
OldValue = oldValue;
NewValue = newValue;
}

public object Owner { get; }
public object OldValue { get; }
public object NewValue { get; }
}
}
203 changes: 138 additions & 65 deletions Xamarin.Forms.Core/Button.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,19 @@
namespace Xamarin.Forms
{
[RenderWith(typeof(_ButtonRenderer))]
public class Button : View, IFontElement, ITextElement, IBorderElement, IButtonController, IElementConfiguration<Button>
public class Button : View, IFontElement, ITextElement, IBorderElement, IButtonController, IElementConfiguration<Button>, IBorderController, IImageController
{
const double DefaultSpacing = 10;
const int DefaultBorderRadius = 5;
const int DefaultCornerRadius = -1;

public static readonly BindableProperty CommandProperty = BindableProperty.Create("Command", typeof(ICommand), typeof(Button), null, propertyChanged: (bo, o, n) => ((Button)bo).OnCommandChanged());
public static readonly BindableProperty CommandProperty = BindableProperty.Create(nameof(Command), typeof(ICommand), typeof(Button), null,
propertyChanging: OnCommandChanging,
propertyChanged: OnCommandChanged
);

public static readonly BindableProperty CommandParameterProperty = BindableProperty.Create("CommandParameter", typeof(object), typeof(Button), null,
propertyChanged: (bindable, oldvalue, newvalue) => ((Button)bindable).CommandCanExecuteChanged(bindable, EventArgs.Empty));
propertyChanged: (bindable, oldvalue, newvalue) => ButtonElementManager.CommandCanExecuteChanged(bindable, EventArgs.Empty));

public static readonly BindableProperty ContentLayoutProperty =
BindableProperty.Create("ContentLayout", typeof(ButtonContentLayout), typeof(Button), new ButtonContentLayout(ButtonContentLayout.ImagePosition.Left, DefaultSpacing));
Expand Down Expand Up @@ -46,10 +49,17 @@ public class Button : View, IFontElement, ITextElement, IBorderElement, IButtonC
public static readonly BindableProperty CornerRadiusProperty = BindableProperty.Create("CornerRadius", typeof(int), typeof(Button), defaultValue: DefaultCornerRadius,
propertyChanged: CornerRadiusPropertyChanged);

public static readonly BindableProperty ImageProperty = BindableProperty.Create("Image", typeof(FileImageSource), typeof(Button), default(FileImageSource),
propertyChanging: (bindable, oldvalue, newvalue) => ((Button)bindable).OnSourcePropertyChanging((ImageSource)oldvalue, (ImageSource)newvalue),
propertyChanged: (bindable, oldvalue, newvalue) => ((Button)bindable).OnSourcePropertyChanged((ImageSource)oldvalue, (ImageSource)newvalue));
public static readonly BindableProperty ImageProperty = BindableProperty.Create(nameof(Image), typeof(FileImageSource), typeof(Button), default(FileImageSource),
propertyChanging: (bindable, oldvalue, newvalue) => ((Button)bindable).OnImagePropertyChanging((ImageSource)oldvalue, (ImageSource)newvalue),
propertyChanged: (bindable, oldvalue, newvalue) => ((Button)bindable).OnImagePropertyChanged((ImageSource)oldvalue, (ImageSource)newvalue));


internal static readonly BindablePropertyKey IsPressedPropertyKey = BindableProperty.CreateReadOnly(nameof(IsPressed), typeof(bool), typeof(Button), default(bool));
public static readonly BindableProperty IsPressedProperty = IsPressedPropertyKey.BindableProperty;

event EventHandler<BindableValueChangedEventArgs> _imageSourceChanged;
event EventHandler<BindableValueChangedEventArgs> _imageSourceChanging;
event EventHandler _imageSourcesSourceChanged;
readonly Lazy<PlatformConfigurationRegistry<Button>> _platformConfigurationRegistry;

public Color BorderColor
Expand Down Expand Up @@ -119,38 +129,41 @@ public Color TextColor
set { SetValue(TextElement.TextColorProperty, value); }
}

bool IsEnabledCore
bool IButtonController.IsEnabledCore
{
set { SetValueCore(IsEnabledProperty, value); }
}

[EditorBrowsable(EditorBrowsableState.Never)]
public void SendClicked()
{
if (IsEnabled == true)
{
Command?.Execute(CommandParameter);
Clicked?.Invoke(this, EventArgs.Empty);
}
}
public void SendClicked() =>
ButtonElementManager.SendClicked(this, this);

public bool IsPressed => (bool)GetValue(IsPressedProperty);


[EditorBrowsable(EditorBrowsableState.Never)]
public void SendPressed()
{
if (IsEnabled == true)
{
Pressed?.Invoke(this, EventArgs.Empty);
}
}
public void SetIsPressed(bool isPressed) =>
SetValue(IsPressedPropertyKey, isPressed);

[EditorBrowsable(EditorBrowsableState.Never)]
public void SendReleased()
{
if (IsEnabled == true)
{
Released?.Invoke(this, EventArgs.Empty);
}
}
public void SendPressed() =>
ButtonElementManager.SendPressed(this, this);

[EditorBrowsable(EditorBrowsableState.Never)]
public void SendReleased() =>
ButtonElementManager.SendReleased(this, this);

[EditorBrowsable(EditorBrowsableState.Never)]
void IButtonController.OnClicked() =>
Clicked?.Invoke(this, EventArgs.Empty);

[EditorBrowsable(EditorBrowsableState.Never)]
void IButtonController.OnPressed() =>
Pressed?.Invoke(this, EventArgs.Empty);

[EditorBrowsable(EditorBrowsableState.Never)]
void IButtonController.OnReleased() =>
Released?.Invoke(this, EventArgs.Empty);

public FontAttributes FontAttributes
{
Expand All @@ -171,22 +184,52 @@ public double FontSize
set { SetValue(FontSizeProperty, value); }
}

public event EventHandler Clicked;
BindableProperty IBorderController.CornerRadiusProperty => Button.CornerRadiusProperty;

BindableProperty IBorderController.BorderColorProperty => Button.BorderColorProperty;

BindableProperty IBorderController.BorderWidthProperty => Button.BorderWidthProperty;

public event EventHandler Pressed;


public event EventHandler Clicked;
public event EventHandler Pressed;
public event EventHandler Released;

event EventHandler<BindableValueChangedEventArgs> _commandChanged;
event EventHandler<BindableValueChangedEventArgs> _commandChanging;
event EventHandler _commandCanExecuteChanged;

event EventHandler<BindableValueChangedEventArgs> IButtonController.CommandChanged { add => _commandChanged += value; remove => _commandChanged -= value; }
event EventHandler<BindableValueChangedEventArgs> IButtonController.CommandChanging { add => _commandChanging += value; remove => _commandChanging -= value; }
event EventHandler IButtonController.CommandCanExecuteChanged { add => _commandCanExecuteChanged += value; remove => _commandCanExecuteChanged -= value; }


public Button()
{
_platformConfigurationRegistry = new Lazy<PlatformConfigurationRegistry<Button>>(() => new PlatformConfigurationRegistry<Button>(this));
ButtonElementManager.Init(this);
ImageElementManager.Init(this);
}


public IPlatformElementConfiguration<T, Button> On<T>() where T : IConfigPlatform
{
return _platformConfigurationRegistry.Value.On<T>();
}

protected override void ChangeVisualState()
{
if (IsEnabled && IsPressed)
{
VisualStateManager.GoToState(this, ButtonElementManager.PressedVisualState);
}
else
{
base.ChangeVisualState();
}
}

protected override void OnBindingContextChanged()
{
FileImageSource image = Image;
Expand All @@ -196,25 +239,6 @@ protected override void OnBindingContextChanged()
base.OnBindingContextChanged();
}

protected override void OnPropertyChanging(string propertyName = null)
{
if (propertyName == CommandProperty.PropertyName)
{
ICommand cmd = Command;
if (cmd != null)
cmd.CanExecuteChanged -= CommandCanExecuteChanged;
}

base.OnPropertyChanging(propertyName);
}

void CommandCanExecuteChanged(object sender, EventArgs eventArgs)
{
ICommand cmd = Command;
if (cmd != null)
IsEnabledCore = cmd.CanExecute(CommandParameter);
}

void IFontElement.OnFontFamilyChanged(string oldValue, string newValue) =>
InvalidateMeasureInternal(InvalidationTrigger.MeasureChanged);

Expand All @@ -230,37 +254,56 @@ void IFontElement.OnFontAttributesChanged(FontAttributes oldValue, FontAttribute
void IFontElement.OnFontChanged(Font oldValue, Font newValue) =>
InvalidateMeasureInternal(InvalidationTrigger.MeasureChanged);

void OnCommandChanged()
Aspect IImageController.Aspect => Aspect.AspectFit;
ImageSource IImageController.Source => Image;
bool IImageController.IsOpaque => false;

BindableProperty IImageController.SourceProperty => ImageProperty;
BindableProperty IImageController.AspectProperty => null;
BindableProperty IImageController.IsOpaqueProperty => null;

event EventHandler<BindableValueChangedEventArgs> IImageController.ImageSourceChanged
{
if (Command != null)
{
Command.CanExecuteChanged += CommandCanExecuteChanged;
CommandCanExecuteChanged(this, EventArgs.Empty);
}
else
IsEnabledCore = true;
add => _imageSourceChanged += value;
remove => _imageSourceChanged -= value;
}

void OnSourceChanged(object sender, EventArgs eventArgs)
event EventHandler<BindableValueChangedEventArgs> IImageController.ImageSourceChanging
{
OnPropertyChanged(ImageProperty.PropertyName);
InvalidateMeasureInternal(InvalidationTrigger.MeasureChanged);
add => _imageSourceChanging += value;
remove => _imageSourceChanging -= value;
}

event EventHandler IImageController.ImageSourcesSourceChanged
{
add => _imageSourcesSourceChanged += value;
remove => _imageSourcesSourceChanged -= value;
}

void OnSourcePropertyChanged(ImageSource oldvalue, ImageSource newvalue)
void IImageController.RaiseImageSourcePropertyChanged() =>
OnPropertyChanged(ImageProperty.PropertyName);

void OnSourceChanged(object sender, EventArgs eventArgs) =>
_imageSourcesSourceChanged?.Invoke(this, EventArgs.Empty);

void OnImagePropertyChanged(ImageSource oldvalue, ImageSource newvalue)
{
if (newvalue != null)
{
newvalue.SourceChanged += OnSourceChanged;
SetInheritedBindingContext(newvalue, BindingContext);
}
InvalidateMeasureInternal(InvalidationTrigger.MeasureChanged);

_imageSourceChanged?.Invoke(this, new BindableValueChangedEventArgs(this, oldvalue, newvalue));
}

void OnSourcePropertyChanging(ImageSource oldvalue, ImageSource newvalue)
void OnImagePropertyChanging(ImageSource oldvalue, ImageSource newvalue)
{
if (oldvalue != null)
{
oldvalue.SourceChanged -= OnSourceChanged;
}

_imageSourceChanging?.Invoke(this, new BindableValueChangedEventArgs(this, oldvalue, newvalue));
}

static void BorderRadiusPropertyChanged(BindableObject bindable, object oldvalue, object newvalue)
Expand Down Expand Up @@ -309,6 +352,36 @@ void IBorderElement.OnBorderColorPropertyChanged(Color oldValue, Color newValue)
{
}

private void OnCommandCanExecuteChanged(object sender, EventArgs e) =>
_commandCanExecuteChanged?.Invoke(this, EventArgs.Empty);

private static void OnCommandChanged(BindableObject bo, object o, object n)
{
var button = (Button)bo;
if (n != null)
{
var newCommand = n as ICommand;
newCommand.CanExecuteChanged += button.OnCommandCanExecuteChanged;
}

button._commandChanged?.Invoke(bo, new BindableValueChangedEventArgs(bo, o, n));
}

private static void OnCommandChanging(BindableObject bo, object o, object n)
{
var button = (Button)bo;
if (o != null)
{
(o as ICommand).CanExecuteChanged -= button.OnCommandCanExecuteChanged;
}

button._commandChanging?.Invoke(bo, new BindableValueChangedEventArgs(bo, o, n));
}

void IImageController.SetIsLoading(bool isLoading)
{
}

[DebuggerDisplay("Image Position = {Position}, Spacing = {Spacing}")]
[TypeConverter(typeof(ButtonContentTypeConverter))]
public sealed class ButtonContentLayout
Expand Down
Loading

0 comments on commit eecce11

Please sign in to comment.