allow to select a date & fix issue
This commit is contained in:
parent
91db3caa15
commit
63ee572e8b
@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using Xamarin.Essentials;
|
using Xamarin.Essentials;
|
||||||
|
using Xamarin.Forms;
|
||||||
|
|
||||||
namespace Billing
|
namespace Billing
|
||||||
{
|
{
|
||||||
@ -73,5 +74,45 @@ namespace Billing
|
|||||||
}
|
}
|
||||||
return color;
|
return color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static bool IsSameDay(DateTime day1, DateTime day2)
|
||||||
|
{
|
||||||
|
return day1.Year == day2.Year && day1.DayOfYear == day2.DayOfYear;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DateTime FirstDay(DateTime date)
|
||||||
|
{
|
||||||
|
var week = date.DayOfWeek;
|
||||||
|
if (week == DayOfWeek.Sunday)
|
||||||
|
{
|
||||||
|
return date;
|
||||||
|
}
|
||||||
|
return date.AddDays(-(int)week);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BindableProperty Create<TResult, TOwner>(string name, TResult defaultValue = default, PropertyValueChanged<TResult, TOwner> propertyChanged = null)
|
||||||
|
where TOwner : BindableObject
|
||||||
|
{
|
||||||
|
if (propertyChanged == null)
|
||||||
|
{
|
||||||
|
return BindableProperty.Create(name, typeof(TResult), typeof(TOwner), defaultValue: defaultValue);
|
||||||
|
}
|
||||||
|
return BindableProperty.Create(name, typeof(TResult), typeof(TOwner),
|
||||||
|
defaultValue: defaultValue,
|
||||||
|
propertyChanged: (obj, old, @new) =>
|
||||||
|
{
|
||||||
|
if (old != null && !(old is TResult))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (@new != null && !(@new is TResult))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
propertyChanged((TOwner)obj, (TResult)old, (TResult)@new);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public delegate void PropertyValueChanged<TResult, TOwner>(TOwner obj, TResult old, TResult @new);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -7,6 +7,7 @@ namespace Billing.Themes
|
|||||||
{
|
{
|
||||||
public static Color CurrentPrimaryColor => (Color)Application.Current.Resources[PrimaryColor];
|
public static Color CurrentPrimaryColor => (Color)Application.Current.Resources[PrimaryColor];
|
||||||
|
|
||||||
|
public const string FontSemiBold = nameof(FontSemiBold);
|
||||||
public const string FontBold = nameof(FontBold);
|
public const string FontBold = nameof(FontBold);
|
||||||
|
|
||||||
public const string WindowBackgroundColor = nameof(WindowBackgroundColor);
|
public const string WindowBackgroundColor = nameof(WindowBackgroundColor);
|
||||||
@ -29,6 +30,7 @@ namespace Billing.Themes
|
|||||||
protected void InitResources()
|
protected void InitResources()
|
||||||
{
|
{
|
||||||
var regularFontFamily = Definition.GetRegularFontFamily();
|
var regularFontFamily = Definition.GetRegularFontFamily();
|
||||||
|
Add(FontSemiBold, Definition.GetSemiBoldFontFamily());
|
||||||
Add(FontBold, Definition.GetBoldFontFamily());
|
Add(FontBold, Definition.GetBoldFontFamily());
|
||||||
|
|
||||||
Add(PrimaryColor, PrimaryMauiColor);
|
Add(PrimaryColor, PrimaryMauiColor);
|
||||||
@ -76,21 +78,18 @@ namespace Billing.Themes
|
|||||||
new Setter { Property = TimePicker.FontFamilyProperty, Value = regularFontFamily }
|
new Setter { Property = TimePicker.FontFamilyProperty, Value = regularFontFamily }
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
Add(new Style(typeof(Button))
|
|
||||||
{
|
|
||||||
Setters =
|
|
||||||
{
|
|
||||||
new Setter { Property = Button.TextColorProperty, Value = SecondaryMauiColor },
|
|
||||||
new Setter { Property = Button.FontFamilyProperty, Value = regularFontFamily },
|
|
||||||
new Setter { Property = VisualElement.BackgroundColorProperty, Value = PrimaryMauiColor },
|
|
||||||
new Setter { Property = Button.PaddingProperty, Value = new Thickness(14, 10) }
|
|
||||||
}
|
|
||||||
});
|
|
||||||
Add(new Style(typeof(TintImage))
|
Add(new Style(typeof(TintImage))
|
||||||
{
|
{
|
||||||
Setters =
|
Setters =
|
||||||
{
|
{
|
||||||
new Setter { Property = TintImage.PrimaryColorProperty, Value = PrimaryMauiColor }
|
new Setter { Property = TintHelper.TintColorProperty, Value = PrimaryMauiColor }
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Add(new Style(typeof(TintImageButton))
|
||||||
|
{
|
||||||
|
Setters =
|
||||||
|
{
|
||||||
|
new Setter { Property = TintHelper.TintColorProperty, Value = PrimaryMauiColor }
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
TextColor="{DynamicResource TextColor}"
|
TextColor="{DynamicResource TextColor}"
|
||||||
FontFamily="{TemplateBinding BillingDay.FontFamily}"
|
FontFamily="{TemplateBinding BillingDay.FontFamily}"
|
||||||
Opacity="{TemplateBinding BillingDay.TextOpacity}"/>
|
Opacity="{TemplateBinding BillingDay.TextOpacity}"/>
|
||||||
<StackLayout Grid.Row="1"
|
<StackLayout Grid.Row="1" Margin="8, 0"
|
||||||
IsVisible="{TemplateBinding BillingDay.IsSelected}"
|
IsVisible="{TemplateBinding BillingDay.IsSelected}"
|
||||||
BackgroundColor="{DynamicResource PrimaryColor}"
|
BackgroundColor="{DynamicResource PrimaryColor}"
|
||||||
Opacity="{TemplateBinding BillingDay.Opacity}"/>
|
Opacity="{TemplateBinding BillingDay.Opacity}"/>
|
||||||
@ -40,7 +40,7 @@
|
|||||||
TextColor="{DynamicResource RedColor}"
|
TextColor="{DynamicResource RedColor}"
|
||||||
FontFamily="{TemplateBinding BillingDay.FontFamily}"
|
FontFamily="{TemplateBinding BillingDay.FontFamily}"
|
||||||
Opacity="{TemplateBinding BillingDay.TextOpacity}"/>
|
Opacity="{TemplateBinding BillingDay.TextOpacity}"/>
|
||||||
<StackLayout Grid.Row="1"
|
<StackLayout Grid.Row="1" Margin="8, 0"
|
||||||
IsVisible="{TemplateBinding BillingDay.IsSelected}"
|
IsVisible="{TemplateBinding BillingDay.IsSelected}"
|
||||||
BackgroundColor="{DynamicResource PrimaryColor}"
|
BackgroundColor="{DynamicResource PrimaryColor}"
|
||||||
Opacity="{TemplateBinding BillingDay.Opacity}"/>
|
Opacity="{TemplateBinding BillingDay.Opacity}"/>
|
||||||
|
@ -7,13 +7,13 @@ namespace Billing.UI
|
|||||||
{
|
{
|
||||||
#region UI Properties
|
#region UI Properties
|
||||||
|
|
||||||
public static readonly BindableProperty SundayProperty = BindableProperty.Create(nameof(Sunday), typeof(BillingDay), typeof(BillingDate));
|
public static readonly BindableProperty SundayProperty = Helper.Create<BillingDay, BillingDate>(nameof(Sunday));
|
||||||
public static readonly BindableProperty MondayProperty = BindableProperty.Create(nameof(Monday), typeof(BillingDay), typeof(BillingDate));
|
public static readonly BindableProperty MondayProperty = Helper.Create<BillingDay, BillingDate>(nameof(Monday));
|
||||||
public static readonly BindableProperty TuesdayProperty = BindableProperty.Create(nameof(Tuesday), typeof(BillingDay), typeof(BillingDate));
|
public static readonly BindableProperty TuesdayProperty = Helper.Create<BillingDay, BillingDate>(nameof(Tuesday));
|
||||||
public static readonly BindableProperty WednesdayProperty = BindableProperty.Create(nameof(Wednesday), typeof(BillingDay), typeof(BillingDate));
|
public static readonly BindableProperty WednesdayProperty = Helper.Create<BillingDay, BillingDate>(nameof(Wednesday));
|
||||||
public static readonly BindableProperty ThursdayProperty = BindableProperty.Create(nameof(Thursday), typeof(BillingDay), typeof(BillingDate));
|
public static readonly BindableProperty ThursdayProperty = Helper.Create<BillingDay, BillingDate>(nameof(Thursday));
|
||||||
public static readonly BindableProperty FridayProperty = BindableProperty.Create(nameof(Friday), typeof(BillingDay), typeof(BillingDate));
|
public static readonly BindableProperty FridayProperty = Helper.Create<BillingDay, BillingDate>(nameof(Friday));
|
||||||
public static readonly BindableProperty SaturdayProperty = BindableProperty.Create(nameof(Saturday), typeof(BillingDay), typeof(BillingDate));
|
public static readonly BindableProperty SaturdayProperty = Helper.Create<BillingDay, BillingDate>(nameof(Saturday));
|
||||||
|
|
||||||
public BillingDay Sunday => (BillingDay)GetValue(SundayProperty);
|
public BillingDay Sunday => (BillingDay)GetValue(SundayProperty);
|
||||||
public BillingDay Monday => (BillingDay)GetValue(MondayProperty);
|
public BillingDay Monday => (BillingDay)GetValue(MondayProperty);
|
||||||
@ -39,38 +39,36 @@ namespace Billing.UI
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static readonly BindableProperty LocatedDateProperty = BindableProperty.Create(nameof(LocatedDate), typeof(DateTime), typeof(BillingDate), propertyChanged: OnLocatedDatePropertyChanged);
|
public static readonly BindableProperty LocatedDateProperty = Helper.Create<DateTime, BillingDate>(nameof(LocatedDate), propertyChanged: OnLocatedDatePropertyChanged);
|
||||||
public static readonly BindableProperty SelectedDateProperty = BindableProperty.Create(nameof(SelectedDate), typeof(DateTime), typeof(BillingDate), propertyChanged: OnSelectedDatePropertyChanged);
|
public static readonly BindableProperty SelectedDateProperty = Helper.Create<DateTime, BillingDate>(nameof(SelectedDate), propertyChanged: OnSelectedDatePropertyChanged);
|
||||||
|
|
||||||
private static void OnLocatedDatePropertyChanged(BindableObject obj, object old, object @new)
|
private static void OnLocatedDatePropertyChanged(BillingDate billingDate, DateTime old, DateTime date)
|
||||||
{
|
{
|
||||||
if (obj is BillingDate billingDate && @new is DateTime date)
|
var week = (int)date.DayOfWeek;
|
||||||
|
var tmpDate = date.AddDays(-week);
|
||||||
|
for (var i = 0; i < 7; i++)
|
||||||
{
|
{
|
||||||
var week = (int)date.DayOfWeek;
|
var day = new BillingDay(tmpDate);
|
||||||
var tmpDate = date.AddDays(-week);
|
billingDate[i] = day;
|
||||||
for (var i = 0; i < 7; i++)
|
tmpDate = tmpDate.AddDays(1);
|
||||||
{
|
|
||||||
var prop = GetWeekProperty(i);
|
|
||||||
var day = new BillingDay(tmpDate);
|
|
||||||
billingDate.SetValue(prop, day);
|
|
||||||
tmpDate = tmpDate.AddDays(1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void OnSelectedDatePropertyChanged(BindableObject obj, object old, object @new)
|
private static void OnSelectedDatePropertyChanged(BillingDate billingDate, DateTime old, DateTime selected)
|
||||||
{
|
{
|
||||||
if (obj is BillingDate billingDate && @new is DateTime selected)
|
for (var i = 0; i < 7; i++)
|
||||||
{
|
{
|
||||||
for (var i = 0; i < 7; i++)
|
var day = billingDate[i];
|
||||||
{
|
day.Refresh(selected);
|
||||||
var prop = GetWeekProperty(i);
|
|
||||||
var day = (BillingDay)billingDate.GetValue(prop);
|
|
||||||
day.Refresh(selected);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public BillingDay this[int index]
|
||||||
|
{
|
||||||
|
get => (BillingDay)GetValue(GetWeekProperty(index));
|
||||||
|
set => SetValue(GetWeekProperty(index), value);
|
||||||
|
}
|
||||||
|
|
||||||
public DateTime LocatedDate
|
public DateTime LocatedDate
|
||||||
{
|
{
|
||||||
get => (DateTime)GetValue(LocatedDateProperty);
|
get => (DateTime)GetValue(LocatedDateProperty);
|
||||||
@ -99,13 +97,26 @@ namespace Billing.UI
|
|||||||
|
|
||||||
public void SetDateTime(DateTime selectedDate, DateTime? locatedDate = null)
|
public void SetDateTime(DateTime selectedDate, DateTime? locatedDate = null)
|
||||||
{
|
{
|
||||||
|
if (Helper.IsSameDay(selectedDate, SelectedDate))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
DateTime located;
|
||||||
if (locatedDate != null)
|
if (locatedDate != null)
|
||||||
{
|
{
|
||||||
LocatedDate = locatedDate.Value;
|
located = Helper.FirstDay(locatedDate.Value);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LocatedDate = selectedDate;
|
located = Helper.FirstDay(selectedDate);
|
||||||
|
}
|
||||||
|
if (LocatedDate != located)
|
||||||
|
{
|
||||||
|
LocatedDate = located;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RestoreState(this[(int)selectedDate.DayOfWeek]);
|
||||||
}
|
}
|
||||||
SelectedDate = selectedDate;
|
SelectedDate = selectedDate;
|
||||||
DateSelected?.Invoke(this, new DateEventArgs(selectedDate));
|
DateSelected?.Invoke(this, new DateEventArgs(selectedDate));
|
||||||
@ -114,43 +125,48 @@ namespace Billing.UI
|
|||||||
private void OnDayChanged(object o)
|
private void OnDayChanged(object o)
|
||||||
{
|
{
|
||||||
var selected = SelectedDate;
|
var selected = SelectedDate;
|
||||||
if (o is BillingDay day && (selected.Year != day.Date.Year || selected.DayOfYear != day.Date.DayOfYear))
|
if (o is BillingDay day && !Helper.IsSameDay(selected, day.Date))
|
||||||
{
|
{
|
||||||
for (var i = 0; i < 7; i++)
|
RestoreState(day);
|
||||||
{
|
|
||||||
var d = (BillingDay)GetValue(GetWeekProperty(i));
|
|
||||||
if (d.IsSelected)
|
|
||||||
{
|
|
||||||
this.AbortAnimation("unselected");
|
|
||||||
this.Animate("unselected", v =>
|
|
||||||
{
|
|
||||||
d.Opacity = v;
|
|
||||||
},
|
|
||||||
start: 1, end: 0,
|
|
||||||
easing: Easing.CubicOut,
|
|
||||||
finished: (v, b) =>
|
|
||||||
{
|
|
||||||
d.Opacity = 0;
|
|
||||||
d.IsSelected = false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SelectedDate = day.Date;
|
SelectedDate = day.Date;
|
||||||
this.AbortAnimation("selected");
|
|
||||||
this.Animate("selected", v =>
|
|
||||||
{
|
|
||||||
day.Opacity = v;
|
|
||||||
},
|
|
||||||
start: 0, end: 1,
|
|
||||||
easing: Easing.CubicOut,
|
|
||||||
finished: (v, b) =>
|
|
||||||
{
|
|
||||||
day.Opacity = 1;
|
|
||||||
});
|
|
||||||
DateSelected?.Invoke(this, new DateEventArgs(day.Date));
|
DateSelected?.Invoke(this, new DateEventArgs(day.Date));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void RestoreState(BillingDay day)
|
||||||
|
{
|
||||||
|
for (var i = 0; i < 7; i++)
|
||||||
|
{
|
||||||
|
var d = (BillingDay)GetValue(GetWeekProperty(i));
|
||||||
|
if (d.IsSelected)
|
||||||
|
{
|
||||||
|
this.AbortAnimation("unselected");
|
||||||
|
this.Animate("unselected", v =>
|
||||||
|
{
|
||||||
|
d.Opacity = v;
|
||||||
|
},
|
||||||
|
start: 1, end: 0,
|
||||||
|
easing: Easing.CubicOut,
|
||||||
|
finished: (v, b) =>
|
||||||
|
{
|
||||||
|
d.Opacity = 0;
|
||||||
|
d.IsSelected = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.AbortAnimation("selected");
|
||||||
|
this.Animate("selected", v =>
|
||||||
|
{
|
||||||
|
day.Opacity = v;
|
||||||
|
},
|
||||||
|
start: 0, end: 1,
|
||||||
|
easing: Easing.CubicOut,
|
||||||
|
finished: (v, b) =>
|
||||||
|
{
|
||||||
|
day.Opacity = 1;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private void OnPanUpdated(object sender, PanUpdatedEventArgs e)
|
private void OnPanUpdated(object sender, PanUpdatedEventArgs e)
|
||||||
{
|
{
|
||||||
if (e.StatusType == GestureStatus.Started)
|
if (e.StatusType == GestureStatus.Started)
|
||||||
@ -176,7 +192,6 @@ namespace Billing.UI
|
|||||||
x1 = null;
|
x1 = null;
|
||||||
var ms = (DateTime.Now - lastDate).TotalMilliseconds;
|
var ms = (DateTime.Now - lastDate).TotalMilliseconds;
|
||||||
var speed = totalX / ms;
|
var speed = totalX / ms;
|
||||||
Helper.Debug($"completed, speed: {speed}");
|
|
||||||
if (speed < -0.7)
|
if (speed < -0.7)
|
||||||
{
|
{
|
||||||
LocatedDate = LocatedDate.AddDays(7);
|
LocatedDate = LocatedDate.AddDays(7);
|
||||||
@ -185,7 +200,7 @@ namespace Billing.UI
|
|||||||
{
|
{
|
||||||
LocatedDate = LocatedDate.AddDays(-7);
|
LocatedDate = LocatedDate.AddDays(-7);
|
||||||
}
|
}
|
||||||
OnSelectedDatePropertyChanged(this, null, SelectedDate);
|
OnSelectedDatePropertyChanged(this, default, SelectedDate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -202,50 +217,37 @@ namespace Billing.UI
|
|||||||
|
|
||||||
public class BillingDayView : ContentView
|
public class BillingDayView : ContentView
|
||||||
{
|
{
|
||||||
public static readonly BindableProperty BillingDayProperty = BindableProperty.Create(nameof(BillingDay), typeof(BillingDay), typeof(BillingDayView));
|
public static readonly BindableProperty BillingDayProperty = Helper.Create<BillingDay, BillingDayView>(nameof(BillingDay));
|
||||||
public static readonly BindableProperty CommandProperty = BindableProperty.Create(nameof(Command), typeof(Command), typeof(BillingDayView));
|
|
||||||
|
|
||||||
public BillingDay BillingDay
|
public BillingDay BillingDay
|
||||||
{
|
{
|
||||||
get => (BillingDay)GetValue(BillingDayProperty);
|
get => (BillingDay)GetValue(BillingDayProperty);
|
||||||
set => SetValue(BillingDayProperty, value);
|
set => SetValue(BillingDayProperty, value);
|
||||||
}
|
}
|
||||||
public Command Command
|
|
||||||
{
|
|
||||||
get => (Command)GetValue(CommandProperty);
|
|
||||||
set => SetValue(CommandProperty, value);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class BillingDay : BindableObject
|
public class BillingDay : BindableObject
|
||||||
{
|
{
|
||||||
public static readonly BindableProperty DateProperty = BindableProperty.Create(nameof(Date), typeof(DateTime), typeof(BillingDay), propertyChanged: OnDatePropertyChanged);
|
public static readonly BindableProperty DateProperty = Helper.Create<DateTime, BillingDay>(nameof(Date), propertyChanged: OnDatePropertyChanged);
|
||||||
public static readonly BindableProperty TextProperty = BindableProperty.Create(nameof(Text), typeof(string), typeof(BillingDay));
|
public static readonly BindableProperty TextProperty = Helper.Create<string, BillingDay>(nameof(Text));
|
||||||
public static readonly BindableProperty FontFamilyProperty = BindableProperty.Create(nameof(FontFamily), typeof(string), typeof(BillingDay), defaultValue: Definition.GetRegularFontFamily());
|
public static readonly BindableProperty FontFamilyProperty = Helper.Create<string, BillingDay>(nameof(FontFamily), defaultValue: Definition.GetRegularFontFamily());
|
||||||
public static readonly BindableProperty IsSelectedProperty = BindableProperty.Create(nameof(IsSelected), typeof(bool), typeof(BillingDay));
|
public static readonly BindableProperty IsSelectedProperty = Helper.Create<bool, BillingDay>(nameof(IsSelected), defaultValue: false);
|
||||||
public static readonly BindableProperty OpacityProperty = BindableProperty.Create(nameof(Opacity), typeof(double), typeof(BillingDay), defaultValue: 1.0);
|
public static readonly BindableProperty OpacityProperty = Helper.Create<double, BillingDay>(nameof(Opacity), defaultValue: 1.0);
|
||||||
public static readonly BindableProperty TextOpacityProperty = BindableProperty.Create(nameof(TextOpacity), typeof(double), typeof(BillingDay), defaultValue: 1.0);
|
public static readonly BindableProperty TextOpacityProperty = Helper.Create<double, BillingDay>(nameof(TextOpacity), defaultValue: 1.0);
|
||||||
|
|
||||||
private static void OnDatePropertyChanged(BindableObject obj, object old, object @new)
|
private static void OnDatePropertyChanged(BillingDay day, DateTime old, DateTime date)
|
||||||
{
|
{
|
||||||
if (obj is BillingDay day && @new is DateTime date)
|
if (date.Day == 1)
|
||||||
{
|
{
|
||||||
if (date.Day == 1)
|
day.SetValue(TextProperty, date.ToString("MMM"));
|
||||||
{
|
}
|
||||||
day.SetValue(TextProperty, date.ToString("MMM"));
|
else
|
||||||
}
|
{
|
||||||
else
|
day.SetValue(TextProperty, date.Day.ToString());
|
||||||
{
|
|
||||||
day.SetValue(TextProperty, date.Day.ToString());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public DateTime Date
|
public DateTime Date => (DateTime)GetValue(DateProperty);
|
||||||
{
|
|
||||||
get => (DateTime)GetValue(DateProperty);
|
|
||||||
set => SetValue(DateProperty, value);
|
|
||||||
}
|
|
||||||
public string Text => (string)GetValue(TextProperty);
|
public string Text => (string)GetValue(TextProperty);
|
||||||
public string FontFamily => (string)GetValue(FontFamilyProperty);
|
public string FontFamily => (string)GetValue(FontFamilyProperty);
|
||||||
public bool IsSelected
|
public bool IsSelected
|
||||||
@ -262,15 +264,15 @@ namespace Billing.UI
|
|||||||
|
|
||||||
public BillingDay(DateTime date)
|
public BillingDay(DateTime date)
|
||||||
{
|
{
|
||||||
Date = date;
|
SetValue(DateProperty, date);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Refresh(DateTime selected)
|
public void Refresh(DateTime selected)
|
||||||
{
|
{
|
||||||
var date = Date;
|
var date = Date;
|
||||||
if (date.Year == selected.Year && date.DayOfYear == selected.DayOfYear)
|
if (Helper.IsSameDay(date, selected))
|
||||||
{
|
{
|
||||||
SetValue(IsSelectedProperty, true);
|
IsSelected = true;
|
||||||
SetValue(FontFamilyProperty, Definition.GetBoldFontFamily());
|
SetValue(FontFamilyProperty, Definition.GetBoldFontFamily());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -3,17 +3,19 @@ using Xamarin.Forms;
|
|||||||
|
|
||||||
namespace Billing.UI
|
namespace Billing.UI
|
||||||
{
|
{
|
||||||
public class TintImage : Image
|
public class TintHelper
|
||||||
{
|
{
|
||||||
public static readonly BindableProperty PrimaryColorProperty = BindableProperty.Create(nameof(PrimaryColor), typeof(Color?), typeof(TintImage));
|
public const string TintColor = nameof(TintColor);
|
||||||
|
public static readonly BindableProperty TintColorProperty = BindableProperty.CreateAttached(TintColor, typeof(Color?), typeof(TintHelper), null);
|
||||||
|
|
||||||
public Color? PrimaryColor
|
public static void SetTintColor(BindableObject obj, Color? color) => obj.SetValue(TintColorProperty, color);
|
||||||
{
|
public static Color? GetTintColor(BindableObject obj) => (Color?)obj.GetValue(TintColorProperty);
|
||||||
get => (Color?)GetValue(PrimaryColorProperty);
|
|
||||||
set => SetValue(PrimaryColorProperty, value);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class TintImage : Image { }
|
||||||
|
|
||||||
|
public class TintImageButton : ImageButton { }
|
||||||
|
|
||||||
public class LongPressButton : Button
|
public class LongPressButton : Button
|
||||||
{
|
{
|
||||||
public event EventHandler LongPressed;
|
public event EventHandler LongPressed;
|
||||||
|
@ -14,6 +14,7 @@ namespace Billing.UI
|
|||||||
public static string PrimaryColorKey = "PrimaryColor";
|
public static string PrimaryColorKey = "PrimaryColor";
|
||||||
public static partial (string main, long build) GetVersion();
|
public static partial (string main, long build) GetVersion();
|
||||||
public static partial string GetRegularFontFamily();
|
public static partial string GetRegularFontFamily();
|
||||||
|
public static partial string GetSemiBoldFontFamily();
|
||||||
public static partial string GetBoldFontFamily();
|
public static partial string GetBoldFontFamily();
|
||||||
public static partial string GetBrandsFontFamily();
|
public static partial string GetBrandsFontFamily();
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
using Billing.Themes;
|
using Billing.Themes;
|
||||||
using System;
|
using System;
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Xamarin.Forms;
|
using Xamarin.Forms;
|
||||||
|
|
||||||
namespace Billing.UI
|
namespace Billing.UI
|
||||||
@ -44,8 +43,8 @@ namespace Billing.UI
|
|||||||
ColumnDefinitions =
|
ColumnDefinitions =
|
||||||
{
|
{
|
||||||
new ColumnDefinition { Width = GridLength.Auto },
|
new ColumnDefinition { Width = GridLength.Auto },
|
||||||
new ColumnDefinition { Width = new GridLength(.3, GridUnitType.Star) },
|
new ColumnDefinition { Width = new GridLength(.35, GridUnitType.Star) },
|
||||||
new ColumnDefinition { Width = new GridLength(.7, GridUnitType.Star) }
|
new ColumnDefinition { Width = new GridLength(.65, GridUnitType.Star) }
|
||||||
},
|
},
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
@ -220,7 +219,7 @@ namespace Billing.UI
|
|||||||
Margin = new Thickness(6, 0)
|
Margin = new Thickness(6, 0)
|
||||||
}
|
}
|
||||||
.Binding(Image.SourceProperty, nameof(ImageSource))
|
.Binding(Image.SourceProperty, nameof(ImageSource))
|
||||||
.Binding(TintImage.PrimaryColorProperty, nameof(TintColor)),
|
.Binding(TintHelper.TintColorProperty, nameof(TintColor)),
|
||||||
|
|
||||||
new TintImage
|
new TintImage
|
||||||
{
|
{
|
||||||
@ -270,7 +269,7 @@ namespace Billing.UI
|
|||||||
protected override View Content => new OptionDatePicker
|
protected override View Content => new OptionDatePicker
|
||||||
{
|
{
|
||||||
HorizontalOptions = LayoutOptions.End,
|
HorizontalOptions = LayoutOptions.End,
|
||||||
VerticalOptions = LayoutOptions.Center
|
VerticalOptions = LayoutOptions.Fill
|
||||||
}
|
}
|
||||||
.Binding(DatePicker.DateProperty, nameof(Date), mode: BindingMode.TwoWay)
|
.Binding(DatePicker.DateProperty, nameof(Date), mode: BindingMode.TwoWay)
|
||||||
.DynamicResource(DatePicker.TextColorProperty, BaseTheme.TextColor)
|
.DynamicResource(DatePicker.TextColorProperty, BaseTheme.TextColor)
|
||||||
@ -290,7 +289,7 @@ namespace Billing.UI
|
|||||||
protected override View Content => new OptionTimePicker
|
protected override View Content => new OptionTimePicker
|
||||||
{
|
{
|
||||||
HorizontalOptions = LayoutOptions.End,
|
HorizontalOptions = LayoutOptions.End,
|
||||||
VerticalOptions = LayoutOptions.Center
|
VerticalOptions = LayoutOptions.Fill
|
||||||
}
|
}
|
||||||
.Binding(TimePicker.TimeProperty, nameof(Time), mode: BindingMode.TwoWay)
|
.Binding(TimePicker.TimeProperty, nameof(Time), mode: BindingMode.TwoWay)
|
||||||
.DynamicResource(TimePicker.TextColorProperty, BaseTheme.TextColor)
|
.DynamicResource(TimePicker.TextColorProperty, BaseTheme.TextColor)
|
||||||
@ -329,7 +328,8 @@ namespace Billing.UI
|
|||||||
{
|
{
|
||||||
HorizontalOptions = LayoutOptions.Fill,
|
HorizontalOptions = LayoutOptions.Fill,
|
||||||
HorizontalTextAlignment = TextAlignment.End,
|
HorizontalTextAlignment = TextAlignment.End,
|
||||||
VerticalOptions = LayoutOptions.Center,
|
VerticalOptions = LayoutOptions.Fill,
|
||||||
|
VerticalTextAlignment = TextAlignment.Center,
|
||||||
ReturnType = ReturnType.Next
|
ReturnType = ReturnType.Next
|
||||||
}
|
}
|
||||||
.Binding(Entry.TextProperty, nameof(Text), mode: BindingMode.TwoWay)
|
.Binding(Entry.TextProperty, nameof(Text), mode: BindingMode.TwoWay)
|
||||||
|
@ -28,9 +28,9 @@
|
|||||||
<!--<Grid.Effects>
|
<!--<Grid.Effects>
|
||||||
<ui:ShadowEffect Offect="0, 3" Color="Black" Opacity=".4"/>
|
<ui:ShadowEffect Offect="0, 3" Color="Black" Opacity=".4"/>
|
||||||
</Grid.Effects>-->
|
</Grid.Effects>-->
|
||||||
<StackLayout VerticalOptions="Center" Margin="20, 0" Spacing="0">
|
<StackLayout VerticalOptions="Center" Margin="20, 0" Spacing="4">
|
||||||
<Label FontSize="Small" Text="{r:Text Balance}"/>
|
<Label FontSize="Small" Text="{r:Text Balance}"/>
|
||||||
<Label FontSize="24" FontFamily="{DynamicResource FontBold}"
|
<Label FontSize="24" FontFamily="{DynamicResource FontSemiBold}"
|
||||||
Text="{Binding Balance, Converter={StaticResource moneyConverter}}"/>
|
Text="{Binding Balance, Converter={StaticResource moneyConverter}}"/>
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
<Grid Grid.Column="1" Margin="20, 0" VerticalOptions="Center" HorizontalOptions="End"
|
<Grid Grid.Column="1" Margin="20, 0" VerticalOptions="Center" HorizontalOptions="End"
|
||||||
|
@ -40,7 +40,7 @@
|
|||||||
Text="{Binding TintColorString, Mode=TwoWay}"/>
|
Text="{Binding TintColorString, Mode=TwoWay}"/>
|
||||||
<ViewCell Height="120">
|
<ViewCell Height="120">
|
||||||
<Grid BackgroundColor="{DynamicResource OptionTintColor}"
|
<Grid BackgroundColor="{DynamicResource OptionTintColor}"
|
||||||
ColumnDefinitions=".3*, .7*" Padding="10">
|
ColumnDefinitions=".35*, .65*" Padding="10">
|
||||||
<ui:ColorPicker Grid.Column="1" ColorChanged="ColorPicker_ColorChanged"/>
|
<ui:ColorPicker Grid.Column="1" ColorChanged="ColorPicker_ColorChanged"/>
|
||||||
</Grid>
|
</Grid>
|
||||||
</ViewCell>
|
</ViewCell>
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
xmlns:r="clr-namespace:Billing.Languages"
|
xmlns:r="clr-namespace:Billing.Languages"
|
||||||
xmlns:ui="clr-namespace:Billing.UI"
|
xmlns:ui="clr-namespace:Billing.UI"
|
||||||
xmlns:v="clr-namespace:Billing.Views"
|
xmlns:v="clr-namespace:Billing.Views"
|
||||||
|
xmlns:ios="clr-namespace:Xamarin.Forms.PlatformConfiguration.iOSSpecific;assembly=Xamarin.Forms.Core"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||||
x:Class="Billing.Views.BillPage"
|
x:Class="Billing.Views.BillPage"
|
||||||
x:DataType="v:BillPage"
|
x:DataType="v:BillPage"
|
||||||
@ -22,23 +23,34 @@
|
|||||||
</ContentPage.Resources>
|
</ContentPage.Resources>
|
||||||
|
|
||||||
<Shell.TitleView>
|
<Shell.TitleView>
|
||||||
<Grid ColumnSpacing="16" ColumnDefinitions="20, *">
|
<Grid ColumnSpacing="16">
|
||||||
<ui:TintImage Source="calendar.png" WidthRequest="20" HeightRequest="20" VerticalOptions="Center"/>
|
<DatePicker x:Name="titleDatePicker" IsVisible="False" Date="{Binding SelectedDate, Mode=TwoWay}"
|
||||||
<ui:LongPressGrid Grid.Column="1" HorizontalOptions="{OnPlatform iOS=Center, Android=Start}"
|
ios:DatePicker.UpdateMode="WhenFinished"
|
||||||
|
DateSelected="TitlePicker_DateSelected"/>
|
||||||
|
<ui:LongPressGrid HorizontalOptions="{OnPlatform iOS=Center, Android=Start}" Padding="30, 0, 0, 0"
|
||||||
VerticalOptions="Center" LongCommand="{Binding TitleLongPressed}">
|
VerticalOptions="Center" LongCommand="{Binding TitleLongPressed}">
|
||||||
<Label Text="{Binding SelectedDate, Converter={StaticResource titleDateConverter}}"
|
<Label Text="{Binding SelectedDate, Converter={StaticResource titleDateConverter}}"
|
||||||
TextColor="{DynamicResource PrimaryColor}"
|
TextColor="{DynamicResource PrimaryColor}"
|
||||||
FontAttributes="Bold" FontSize="20"/>
|
FontSize="{OnPlatform Android=20, iOS=18}">
|
||||||
|
<Label.FontFamily>
|
||||||
|
<OnPlatform x:TypeArguments="x:String"
|
||||||
|
Android="OpenSans-SemiBold.ttf#OpenSans-SemiBold"
|
||||||
|
iOS="OpenSans-Bold"/>
|
||||||
|
</Label.FontFamily>
|
||||||
|
</Label>
|
||||||
</ui:LongPressGrid>
|
</ui:LongPressGrid>
|
||||||
|
<ui:TintImageButton Source="calendar.png" WidthRequest="20" HeightRequest="20"
|
||||||
|
VerticalOptions="Center" HorizontalOptions="Start"
|
||||||
|
Command="{Binding TitleDateTap}"/>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Shell.TitleView>
|
</Shell.TitleView>
|
||||||
|
|
||||||
<ContentPage.ToolbarItems>
|
<ContentPage.ToolbarItems>
|
||||||
<ToolbarItem Order="Primary" IconImageSource="plus.png" Command="{Binding EditBilling}"/>
|
<ToolbarItem Order="Primary" Priority="1" IconImageSource="plus.png" Command="{Binding EditBilling}"/>
|
||||||
</ContentPage.ToolbarItems>
|
</ContentPage.ToolbarItems>
|
||||||
|
|
||||||
<Grid RowDefinitions="Auto, Auto, *">
|
<Grid RowDefinitions="Auto, Auto, *">
|
||||||
<ui:BillingDate x:Name="billingDate" SelectedDate="{Binding SelectedDate}" DateSelected="OnDateSelected"/>
|
<ui:BillingDate x:Name="billingDate" DateSelected="OnDateSelected"/>
|
||||||
<Grid Grid.Row="1" Padding="8" ColumnSpacing="8" ColumnDefinitions="*, Auto"
|
<Grid Grid.Row="1" Padding="8" ColumnSpacing="8" ColumnDefinitions="*, Auto"
|
||||||
BackgroundColor="{DynamicResource PromptBackgroundColor}"
|
BackgroundColor="{DynamicResource PromptBackgroundColor}"
|
||||||
IsVisible="{Binding NoBills}">
|
IsVisible="{Binding NoBills}">
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
using Billing.Languages;
|
|
||||||
using Billing.Models;
|
using Billing.Models;
|
||||||
using Billing.UI;
|
using Billing.UI;
|
||||||
using System;
|
using System;
|
||||||
@ -13,12 +12,19 @@ namespace Billing.Views
|
|||||||
{
|
{
|
||||||
public partial class BillPage : BillingPage
|
public partial class BillPage : BillingPage
|
||||||
{
|
{
|
||||||
private static readonly BindableProperty SelectedDateProperty = BindableProperty.Create(nameof(SelectedDate), typeof(DateTime), typeof(BillPage));
|
private static readonly DateTime dateNow = DateTime.Today;
|
||||||
private static readonly BindableProperty BillsProperty = BindableProperty.Create(nameof(Bills), typeof(List<UIBill>), typeof(BillPage));
|
|
||||||
private static readonly BindableProperty NoBillsProperty = BindableProperty.Create(nameof(NoBills), typeof(bool), typeof(BillPage));
|
private static readonly BindableProperty SelectedDateProperty = Helper.Create<DateTime, BillPage>(nameof(SelectedDate), defaultValue: dateNow, propertyChanged: OnSelectedDateChanged);
|
||||||
private static readonly BindableProperty IncomeProperty = BindableProperty.Create(nameof(Income), typeof(decimal), typeof(BillPage));
|
private static readonly BindableProperty BillsProperty = Helper.Create<List<UIBill>, BillPage>(nameof(Bills));
|
||||||
private static readonly BindableProperty SpendingProperty = BindableProperty.Create(nameof(Spending), typeof(decimal), typeof(BillPage));
|
private static readonly BindableProperty NoBillsProperty = Helper.Create<bool, BillPage>(nameof(NoBills));
|
||||||
private static readonly BindableProperty BalanceProperty = BindableProperty.Create(nameof(Balance), typeof(decimal), typeof(BillPage));
|
private static readonly BindableProperty IncomeProperty = Helper.Create<decimal, BillPage>(nameof(Income));
|
||||||
|
private static readonly BindableProperty SpendingProperty = Helper.Create<decimal, BillPage>(nameof(Spending));
|
||||||
|
private static readonly BindableProperty BalanceProperty = Helper.Create<decimal, BillPage>(nameof(Balance));
|
||||||
|
|
||||||
|
private static void OnSelectedDateChanged(BillPage page, DateTime old, DateTime @new)
|
||||||
|
{
|
||||||
|
page.titleDatePicker.Unfocus();
|
||||||
|
}
|
||||||
|
|
||||||
public DateTime SelectedDate
|
public DateTime SelectedDate
|
||||||
{
|
{
|
||||||
@ -35,20 +41,21 @@ namespace Billing.Views
|
|||||||
public decimal Spending => (decimal)GetValue(SpendingProperty);
|
public decimal Spending => (decimal)GetValue(SpendingProperty);
|
||||||
public decimal Balance => (decimal)GetValue(BalanceProperty);
|
public decimal Balance => (decimal)GetValue(BalanceProperty);
|
||||||
|
|
||||||
|
public Command TitleDateTap { get; }
|
||||||
public Command TitleLongPressed { get; }
|
public Command TitleLongPressed { get; }
|
||||||
public Command EditBilling { get; }
|
public Command EditBilling { get; }
|
||||||
public Command DeleteBilling { get; }
|
public Command DeleteBilling { get; }
|
||||||
|
|
||||||
public BillPage()
|
public BillPage()
|
||||||
{
|
{
|
||||||
|
TitleDateTap = new Command(OnTitleDateTapped);
|
||||||
TitleLongPressed = new Command(OnTitleDateLongPressed);
|
TitleLongPressed = new Command(OnTitleDateLongPressed);
|
||||||
EditBilling = new Command(OnEditBilling);
|
EditBilling = new Command(OnEditBilling);
|
||||||
DeleteBilling = new Command(OnDeleteBilling);
|
DeleteBilling = new Command(OnDeleteBilling);
|
||||||
|
|
||||||
SelectedDate = DateTime.Now;
|
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
|
||||||
billingDate.SetDateTime(DateTime.Now);
|
billingDate.SetDateTime(dateNow);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnDateSelected(object sender, DateEventArgs e)
|
private void OnDateSelected(object sender, DateEventArgs e)
|
||||||
@ -57,10 +64,7 @@ namespace Billing.Views
|
|||||||
|
|
||||||
Task.Run(() =>
|
Task.Run(() =>
|
||||||
{
|
{
|
||||||
var bills = App.Bills.Where(b =>
|
var bills = App.Bills.Where(b => Helper.IsSameDay(b.CreateTime, e.Date));
|
||||||
b.CreateTime.Year == e.Date.Year &&
|
|
||||||
b.CreateTime.Month == e.Date.Month &&
|
|
||||||
b.CreateTime.Day == e.Date.Day);
|
|
||||||
Bills = new List<UIBill>(bills.OrderBy(b => b.CreateTime).Select(b => WrapBill(b)));
|
Bills = new List<UIBill>(bills.OrderBy(b => b.CreateTime).Select(b => WrapBill(b)));
|
||||||
RefreshBalance(Bills);
|
RefreshBalance(Bills);
|
||||||
MainThread.BeginInvokeOnMainThread(async () => await scrollView.ScrollToAsync(0, 0, true));
|
MainThread.BeginInvokeOnMainThread(async () => await scrollView.ScrollToAsync(0, 0, true));
|
||||||
@ -98,9 +102,19 @@ namespace Billing.Views
|
|||||||
bill.Wallet = App.Accounts.FirstOrDefault(a => a.Id == bill.Bill.WalletId)?.Name;
|
bill.Wallet = App.Accounts.FirstOrDefault(a => a.Id == bill.Bill.WalletId)?.Name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnTitleDateTapped()
|
||||||
|
{
|
||||||
|
titleDatePicker.Focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void TitlePicker_DateSelected(object sender, DateChangedEventArgs e)
|
||||||
|
{
|
||||||
|
billingDate.SetDateTime(e.NewDate);
|
||||||
|
}
|
||||||
|
|
||||||
private void OnTitleDateLongPressed()
|
private void OnTitleDateLongPressed()
|
||||||
{
|
{
|
||||||
billingDate.SetDateTime(DateTime.Now);
|
billingDate.SetDateTime(DateTime.Today);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void OnEditBilling(object o)
|
private async void OnEditBilling(object o)
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
CommandParameter="{Binding .}"/>
|
CommandParameter="{Binding .}"/>
|
||||||
</Grid.GestureRecognizers>
|
</Grid.GestureRecognizers>
|
||||||
<ui:TintImage Source="{Binding Icon, Converter={StaticResource iconConverter}}"
|
<ui:TintImage Source="{Binding Icon, Converter={StaticResource iconConverter}}"
|
||||||
PrimaryColor="{Binding TintColor}"
|
ui:TintHelper.TintColor="{Binding TintColor}"
|
||||||
WidthRequest="26" HeightRequest="20" VerticalOptions="Center"/>
|
WidthRequest="26" HeightRequest="20" VerticalOptions="Center"/>
|
||||||
<Label Grid.Column="1" Text="{Binding Name}" TextColor="{DynamicResource TextColor}"
|
<Label Grid.Column="1" Text="{Binding Name}" TextColor="{DynamicResource TextColor}"
|
||||||
HorizontalOptions="FillAndExpand" VerticalOptions="Center"
|
HorizontalOptions="FillAndExpand" VerticalOptions="Center"
|
||||||
|
@ -36,7 +36,7 @@
|
|||||||
CommandParameter="{Binding .}"/>
|
CommandParameter="{Binding .}"/>
|
||||||
</Grid.GestureRecognizers>
|
</Grid.GestureRecognizers>
|
||||||
<ui:TintImage Source="{Binding Icon, Converter={StaticResource iconConverter}}"
|
<ui:TintImage Source="{Binding Icon, Converter={StaticResource iconConverter}}"
|
||||||
PrimaryColor="{Binding TintColor}"
|
ui:TintHelper.TintColor="{Binding TintColor}"
|
||||||
WidthRequest="26" HeightRequest="20" VerticalOptions="Center"/>
|
WidthRequest="26" HeightRequest="20" VerticalOptions="Center"/>
|
||||||
<Label Grid.Column="1" Text="{Binding Name}" TextColor="{DynamicResource TextColor}"
|
<Label Grid.Column="1" Text="{Binding Name}" TextColor="{DynamicResource TextColor}"
|
||||||
HorizontalOptions="FillAndExpand" VerticalOptions="Center"
|
HorizontalOptions="FillAndExpand" VerticalOptions="Center"
|
||||||
@ -58,7 +58,7 @@
|
|||||||
CommandParameter="{Binding .}"/>
|
CommandParameter="{Binding .}"/>
|
||||||
</Grid.GestureRecognizers>
|
</Grid.GestureRecognizers>
|
||||||
<ui:TintImage Source="{Binding Icon, Converter={StaticResource iconConverter}}"
|
<ui:TintImage Source="{Binding Icon, Converter={StaticResource iconConverter}}"
|
||||||
PrimaryColor="{Binding TintColor}"
|
ui:TintHelper.TintColor="{Binding TintColor}"
|
||||||
WidthRequest="26" HeightRequest="20" VerticalOptions="Center"/>
|
WidthRequest="26" HeightRequest="20" VerticalOptions="Center"/>
|
||||||
<Label Grid.Column="1" Text="{Binding Name}" TextColor="{DynamicResource TextColor}"
|
<Label Grid.Column="1" Text="{Binding Name}" TextColor="{DynamicResource TextColor}"
|
||||||
HorizontalOptions="FillAndExpand" VerticalOptions="Center"
|
HorizontalOptions="FillAndExpand" VerticalOptions="Center"
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
Keyboard="Text"/>
|
Keyboard="Text"/>
|
||||||
<ViewCell Height="120">
|
<ViewCell Height="120">
|
||||||
<Grid BackgroundColor="{DynamicResource OptionTintColor}"
|
<Grid BackgroundColor="{DynamicResource OptionTintColor}"
|
||||||
ColumnDefinitions=".3*, .7*" Padding="10">
|
ColumnDefinitions=".35*, .65*" Padding="10">
|
||||||
<!--<Label Text="" LineBreakMode="TailTruncation"
|
<!--<Label Text="" LineBreakMode="TailTruncation"
|
||||||
VerticalOptions="Center"
|
VerticalOptions="Center"
|
||||||
TextColor="{DynamicResource TextColor}"/>-->
|
TextColor="{DynamicResource TextColor}"/>-->
|
||||||
|
BIN
Billing/Billing.Android/Assets/OpenSans-SemiBold.ttf
Normal file
BIN
Billing/Billing.Android/Assets/OpenSans-SemiBold.ttf
Normal file
Binary file not shown.
@ -84,6 +84,7 @@
|
|||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="Renderers\OptionEditorRenderer.cs" />
|
<Compile Include="Renderers\OptionEditorRenderer.cs" />
|
||||||
<Compile Include="SplashActivity.cs" />
|
<Compile Include="SplashActivity.cs" />
|
||||||
|
<Compile Include="Renderers\TintImageButtonRenderer.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<AndroidAsset Include="Assets\fa-brands-400.ttf" />
|
<AndroidAsset Include="Assets\fa-brands-400.ttf" />
|
||||||
@ -92,6 +93,7 @@
|
|||||||
<None Include="Resources\AboutResources.txt" />
|
<None Include="Resources\AboutResources.txt" />
|
||||||
<None Include="Assets\AboutAssets.txt" />
|
<None Include="Assets\AboutAssets.txt" />
|
||||||
<None Include="Properties\AndroidManifest.xml" />
|
<None Include="Properties\AndroidManifest.xml" />
|
||||||
|
<AndroidAsset Include="Assets\OpenSans-SemiBold.ttf" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<AndroidResource Include="Resources\values\styles.xml" />
|
<AndroidResource Include="Resources\values\styles.xml" />
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
return (version, build);
|
return (version, build);
|
||||||
}
|
}
|
||||||
public static partial string GetRegularFontFamily() => "OpenSans-Regular.ttf#OpenSans-Regular";
|
public static partial string GetRegularFontFamily() => "OpenSans-Regular.ttf#OpenSans-Regular";
|
||||||
|
public static partial string GetSemiBoldFontFamily() => "OpenSans-SemiBold.ttf#OpenSans-SemiBold";
|
||||||
public static partial string GetBoldFontFamily() => "OpenSans-Bold.ttf#OpenSans-Bold";
|
public static partial string GetBoldFontFamily() => "OpenSans-Bold.ttf#OpenSans-Bold";
|
||||||
public static partial string GetBrandsFontFamily() => "fa-brands-400.ttf#FontAwesome6Brands-Regular";
|
public static partial string GetBrandsFontFamily() => "fa-brands-400.ttf#FontAwesome6Brands-Regular";
|
||||||
}
|
}
|
||||||
|
41
Billing/Billing.Android/Renderers/TintImageButtonRenderer.cs
Normal file
41
Billing/Billing.Android/Renderers/TintImageButtonRenderer.cs
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
using System.ComponentModel;
|
||||||
|
using Android.Content;
|
||||||
|
using Billing.Droid.Renderers;
|
||||||
|
using Billing.UI;
|
||||||
|
using Xamarin.Forms;
|
||||||
|
using Xamarin.Forms.Platform.Android;
|
||||||
|
|
||||||
|
[assembly: ExportRenderer(typeof(TintImageButton), typeof(TintImageButtonRenderer))]
|
||||||
|
namespace Billing.Droid.Renderers
|
||||||
|
{
|
||||||
|
public class TintImageButtonRenderer : ImageButtonRenderer
|
||||||
|
{
|
||||||
|
public TintImageButtonRenderer(Context context) : base(context)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||||
|
{
|
||||||
|
base.OnElementPropertyChanged(sender, e);
|
||||||
|
|
||||||
|
if (e.PropertyName == TintHelper.TintColor ||
|
||||||
|
e.PropertyName == nameof(Image.Source))
|
||||||
|
{
|
||||||
|
if (Drawable != null && Element is TintImageButton image)
|
||||||
|
{
|
||||||
|
Drawable.SetTint(TintHelper.GetTintColor(image)?.ToAndroid() ?? 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnElementChanged(ElementChangedEventArgs<ImageButton> e)
|
||||||
|
{
|
||||||
|
base.OnElementChanged(e);
|
||||||
|
|
||||||
|
if (Drawable != null && Element is TintImageButton image)
|
||||||
|
{
|
||||||
|
Drawable.SetTint(TintHelper.GetTintColor(image)?.ToAndroid() ?? 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -18,12 +18,12 @@ namespace Billing.Droid.Renderers
|
|||||||
{
|
{
|
||||||
base.OnElementPropertyChanged(sender, e);
|
base.OnElementPropertyChanged(sender, e);
|
||||||
|
|
||||||
if (e.PropertyName == nameof(TintImage.PrimaryColor) ||
|
if (e.PropertyName == TintHelper.TintColor ||
|
||||||
e.PropertyName == nameof(Image.Source))
|
e.PropertyName == nameof(Image.Source))
|
||||||
{
|
{
|
||||||
if (Control?.Drawable != null && Element is TintImage image)
|
if (Control?.Drawable != null && Element is TintImage image)
|
||||||
{
|
{
|
||||||
Control.Drawable.SetTint(image.PrimaryColor?.ToAndroid() ?? 0);
|
Control.Drawable.SetTint(TintHelper.GetTintColor(image)?.ToAndroid() ?? 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -34,7 +34,7 @@ namespace Billing.Droid.Renderers
|
|||||||
|
|
||||||
if (Control?.Drawable != null && Element is TintImage image)
|
if (Control?.Drawable != null && Element is TintImage image)
|
||||||
{
|
{
|
||||||
Control.Drawable.SetTint(image.PrimaryColor?.ToAndroid() ?? 0);
|
Control.Drawable.SetTint(TintHelper.GetTintColor(image)?.ToAndroid() ?? 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ namespace Billing.Droid
|
|||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Xamarin.Android.Build.Tasks", "12.2.0.155")]
|
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Xamarin.Android.Build.Tasks", "1.0.0.0")]
|
||||||
public partial class Resource
|
public partial class Resource
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -87,6 +87,8 @@
|
|||||||
<Compile Include="Renderers\BillingPageRenderer.cs" />
|
<Compile Include="Renderers\BillingPageRenderer.cs" />
|
||||||
<BundleResource Include="Resources\OpenSans-Bold.ttf" />
|
<BundleResource Include="Resources\OpenSans-Bold.ttf" />
|
||||||
<BundleResource Include="Resources\OpenSans-Regular.ttf" />
|
<BundleResource Include="Resources\OpenSans-Regular.ttf" />
|
||||||
|
<Compile Include="Renderers\TintImageButtonRenderer.cs" />
|
||||||
|
<BundleResource Include="Resources\OpenSans-SemiBold.ttf" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ImageAsset Include="Assets.xcassets\AppIcon.appiconset\Contents.json">
|
<ImageAsset Include="Assets.xcassets\AppIcon.appiconset\Contents.json">
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
int.Parse(Foundation.NSBundle.MainBundle.ObjectForInfoDictionary("CFBundleVersion").ToString())
|
int.Parse(Foundation.NSBundle.MainBundle.ObjectForInfoDictionary("CFBundleVersion").ToString())
|
||||||
);
|
);
|
||||||
public static partial string GetRegularFontFamily() => "OpenSans-Regular";
|
public static partial string GetRegularFontFamily() => "OpenSans-Regular";
|
||||||
|
public static partial string GetSemiBoldFontFamily() => "OpenSans-SemiBold";
|
||||||
public static partial string GetBoldFontFamily() => "OpenSans-Bold";
|
public static partial string GetBoldFontFamily() => "OpenSans-Bold";
|
||||||
public static partial string GetBrandsFontFamily() => "FontAwesome6Brands-Regular";
|
public static partial string GetBrandsFontFamily() => "FontAwesome6Brands-Regular";
|
||||||
}
|
}
|
||||||
|
@ -39,6 +39,7 @@
|
|||||||
<string>fa-brands-400.ttf</string>
|
<string>fa-brands-400.ttf</string>
|
||||||
<string>OpenSans-Bold.ttf</string>
|
<string>OpenSans-Bold.ttf</string>
|
||||||
<string>OpenSans-Regular.ttf</string>
|
<string>OpenSans-Regular.ttf</string>
|
||||||
|
<string>OpenSans-SemiBold.ttf</string>
|
||||||
</array>
|
</array>
|
||||||
<key>UIFileSharingEnabled</key>
|
<key>UIFileSharingEnabled</key>
|
||||||
<true/>
|
<true/>
|
||||||
|
@ -8,6 +8,48 @@ namespace Billing.iOS.Renderers
|
|||||||
{
|
{
|
||||||
public class BillingPageRenderer : PageRenderer
|
public class BillingPageRenderer : PageRenderer
|
||||||
{
|
{
|
||||||
|
/* Custom navigation left button, but has an issue
|
||||||
|
public override void ViewWillAppear(bool animated)
|
||||||
|
{
|
||||||
|
base.ViewWillAppear(animated);
|
||||||
|
|
||||||
|
var navigationItem = NavigationController?.TopViewController.NavigationItem;
|
||||||
|
if (navigationItem == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Element is BillingPage page)
|
||||||
|
{
|
||||||
|
var itemsInfo = page.ToolbarItems;
|
||||||
|
var leftButtons = navigationItem.LeftBarButtonItems?.ToList() ?? new();
|
||||||
|
var rightButtons = navigationItem.RightBarButtonItems?.ToList() ?? new();
|
||||||
|
|
||||||
|
for (var i = rightButtons.Count - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
var item = rightButtons[i];
|
||||||
|
var info = itemsInfo[i];
|
||||||
|
if (info == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (info.Priority == 1)
|
||||||
|
{
|
||||||
|
item.Style = UIBarButtonItemStyle.Done;
|
||||||
|
}
|
||||||
|
else if (info.Priority == -1)
|
||||||
|
{
|
||||||
|
rightButtons.Remove(item);
|
||||||
|
leftButtons.Add(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
navigationItem.RightBarButtonItems = rightButtons.ToArray();
|
||||||
|
navigationItem.LeftBarButtonItems = leftButtons.ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//*/
|
||||||
|
|
||||||
public override void ViewDidAppear(bool animated)
|
public override void ViewDidAppear(bool animated)
|
||||||
{
|
{
|
||||||
base.ViewDidAppear(animated);
|
base.ViewDidAppear(animated);
|
||||||
|
49
Billing/Billing.iOS/Renderers/TintImageButtonRenderer.cs
Normal file
49
Billing/Billing.iOS/Renderers/TintImageButtonRenderer.cs
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
using System.ComponentModel;
|
||||||
|
using Billing.iOS.Renderers;
|
||||||
|
using Billing.UI;
|
||||||
|
using UIKit;
|
||||||
|
using Xamarin.Forms;
|
||||||
|
using Xamarin.Forms.Platform.iOS;
|
||||||
|
|
||||||
|
[assembly: ExportRenderer(typeof(TintImageButton), typeof(TintImageButtonRenderer))]
|
||||||
|
namespace Billing.iOS.Renderers
|
||||||
|
{
|
||||||
|
public class TintImageButtonRenderer : ImageButtonRenderer
|
||||||
|
{
|
||||||
|
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||||
|
{
|
||||||
|
base.OnElementPropertyChanged(sender, e);
|
||||||
|
|
||||||
|
if (Control == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.PropertyName == nameof(Image.Source) ||
|
||||||
|
e.PropertyName == TintHelper.TintColor)
|
||||||
|
{
|
||||||
|
var img = Control.ImageForState(UIControlState.Normal);
|
||||||
|
if (img != null && Element is TintImageButton image)
|
||||||
|
{
|
||||||
|
Control.SetImage(img.ImageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate), UIControlState.Normal);
|
||||||
|
Control.TintColor = TintHelper.GetTintColor(image)?.ToUIColor();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnElementChanged(ElementChangedEventArgs<ImageButton> e)
|
||||||
|
{
|
||||||
|
base.OnElementChanged(e);
|
||||||
|
|
||||||
|
if (Control != null && Element is TintImageButton image)
|
||||||
|
{
|
||||||
|
var img = Control.ImageForState(UIControlState.Normal);
|
||||||
|
if (img != null)
|
||||||
|
{
|
||||||
|
Control.SetImage(img.ImageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate), UIControlState.Normal);
|
||||||
|
Control.TintColor = TintHelper.GetTintColor(image)?.ToUIColor();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -9,7 +9,6 @@ namespace Billing.iOS.Renderers
|
|||||||
{
|
{
|
||||||
public class TintImageRenderer : ImageRenderer
|
public class TintImageRenderer : ImageRenderer
|
||||||
{
|
{
|
||||||
|
|
||||||
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
|
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||||
{
|
{
|
||||||
base.OnElementPropertyChanged(sender, e);
|
base.OnElementPropertyChanged(sender, e);
|
||||||
@ -20,15 +19,16 @@ namespace Billing.iOS.Renderers
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (e.PropertyName == nameof(Image.Source) ||
|
if (e.PropertyName == nameof(Image.Source) ||
|
||||||
e.PropertyName == nameof(TintImage.PrimaryColor))
|
e.PropertyName == TintHelper.TintColor)
|
||||||
{
|
{
|
||||||
Control.Image = Control.Image.ImageWithRenderingMode(UIKit.UIImageRenderingMode.AlwaysTemplate);
|
if (Control.Image != null && Element is TintImage image)
|
||||||
if (Element is TintImage image)
|
|
||||||
{
|
{
|
||||||
Control.TintColor = image.PrimaryColor?.ToUIColor();
|
Control.Image = Control.Image.ImageWithRenderingMode(UIKit.UIImageRenderingMode.AlwaysTemplate);
|
||||||
|
Control.TintColor = TintHelper.GetTintColor(image)?.ToUIColor();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnElementChanged(ElementChangedEventArgs<Image> e)
|
protected override void OnElementChanged(ElementChangedEventArgs<Image> e)
|
||||||
{
|
{
|
||||||
base.OnElementChanged(e);
|
base.OnElementChanged(e);
|
||||||
@ -38,7 +38,7 @@ namespace Billing.iOS.Renderers
|
|||||||
if (Control.Image != null)
|
if (Control.Image != null)
|
||||||
{
|
{
|
||||||
Control.Image = Control.Image.ImageWithRenderingMode(UIKit.UIImageRenderingMode.AlwaysTemplate);
|
Control.Image = Control.Image.ImageWithRenderingMode(UIKit.UIImageRenderingMode.AlwaysTemplate);
|
||||||
Control.TintColor = image.PrimaryColor?.ToUIColor();
|
Control.TintColor = TintHelper.GetTintColor(image)?.ToUIColor();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
BIN
Billing/Billing.iOS/Resources/OpenSans-SemiBold.ttf
Normal file
BIN
Billing/Billing.iOS/Resources/OpenSans-SemiBold.ttf
Normal file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user