Added parsing Cor-specific elements

amazfit_cor
Valeriy Mironov 2018-01-13 15:58:37 +02:00
parent e356074f66
commit 9ead83d0db
25 changed files with 249 additions and 62 deletions

View File

@ -35,7 +35,7 @@ namespace Resources.Image
if (_paletteColors > 0)
ReadPalette();
else if (_bitsPerPixel == 16 || _bitsPerPixel == 24 || _bitsPerPixel == 32)
Logger.Debug("The image doesn't use a palette.");
Logger.Trace("The image doesn't use a palette.");
else
throw new ArgumentException("The image format is not supported. Please report the issue on https://bitbucket.org/valeronm/amazfitbiptools");
return ReadImage();
@ -70,12 +70,7 @@ namespace Resources.Image
if (padding != 0) Logger.Warn("Palette item {0} last byte is not zero: {1:X2}", i, padding);
var isColorValid = (r == 0 || r == 0xff) && (g == 0 || g == 0xff) && (b == 0 || b == 0xff);
if (isColorValid)
Logger.Trace("Palette item {0}: R {1:X2}, G {2:X2}, B {3:X2}", i, r, g, b);
else
Logger.Warn("Palette item {0}: R {1:X2}, G {2:X2}, B {3:X2}, color isn't supported!", i, r, g, b);
Logger.Trace("Palette item {0}: R {1:X2}, G {2:X2}, B {3:X2}", i, r, g, b);
var alpha = _transparency && i == 0 ? 0x00 : 0xff;
_palette[i] = Color.FromArgb(alpha, r, g, b);

View File

@ -7,16 +7,16 @@ namespace WatchFace.Parser.Elements
public class Activity
{
[ParameterId(1)]
public Number Steps { get; set; }
public CompositeNumber Steps { get; set; }
[ParameterId(2)]
public Number StepsGoal { get; set; }
public CompositeNumber StepsGoal { get; set; }
[ParameterId(3)]
public Number Calories { get; set; }
public CompositeNumber Calories { get; set; }
[ParameterId(4)]
public Number Pulse { get; set; }
public CompositeNumber Pulse { get; set; }
[ParameterId(5)]
public FormattedNumber Distance { get; set; }

View File

@ -0,0 +1,23 @@
using WatchFace.Parser.Attributes;
using WatchFace.Parser.Elements.BasicElements;
namespace WatchFace.Parser.Elements.ActivityElements
{
public class CompositeNumber
{
[ParameterId(1)]
public Number Number { get; set; }
[ParameterId(2)]
[ParameterImageIndex]
public long? PrefixImageIndex { get; set; }
[ParameterId(3)]
[ParameterImageIndex]
public long? EmptyImageIndex { get; set; }
[ParameterId(4)]
[ParameterImageIndex]
public long? SuffixImageIndex { get; set; }
}
}

View File

@ -3,21 +3,21 @@ using WatchFace.Parser.Elements.BasicElements;
namespace WatchFace.Parser.Elements
{
public class Unknown12
public class AnalogDialBitmaps
{
[ParameterId(1)]
public UnknownBlock Unknown1 { get; set; }
public Rectangle RedrawBlock { get; set; }
[ParameterId(2)]
public Image Unknown2 { get; set; }
public Image Hours { get; set; }
[ParameterId(3)]
public Image Unknown3 { get; set; }
public Image Minutes { get; set; }
[ParameterId(4)]
public Image Unknown4 { get; set; }
public Image Seconds { get; set; }
[ParameterId(5)]
public Image Unknown5 { get; set; }
public Image CenterImage { get; set; }
}
}

View File

@ -3,7 +3,7 @@ using WatchFace.Parser.Elements.AnalogDialFaceElements;
namespace WatchFace.Parser.Elements
{
public class AnalogDialFace
public class AnalogDialVector
{
[ParameterId(1)]
public ClockHand Hours { get; set; }

View File

@ -2,13 +2,13 @@
namespace WatchFace.Parser.Elements.BasicElements
{
public class UnknownBlock
public class Rectangle
{
[ParameterId(1)]
public long TopLeftX { get; set; }
public long X { get; set; }
[ParameterId(2)]
public long TopLeftY { get; set; }
public long Y { get; set; }
[ParameterId(3)]
public long BottomRightX { get; set; }

View File

@ -1,4 +1,5 @@
using WatchFace.Parser.Attributes;
using WatchFace.Parser.Elements.ActivityElements;
using WatchFace.Parser.Elements.BasicElements;
namespace WatchFace.Parser.Elements
@ -6,7 +7,7 @@ namespace WatchFace.Parser.Elements
public class Battery
{
[ParameterId(1)]
public Number Text { get; set; }
public CompositeNumber Text { get; set; }
[ParameterId(2)]
public ImageSet Icon { get; set; }

View File

@ -0,0 +1,11 @@
using WatchFace.Parser.Attributes;
using WatchFace.Parser.Elements.BasicElements;
namespace WatchFace.Parser.Elements
{
public class PulseProgress
{
[ParameterId(1)]
public Scale Linear { get; set; }
}
}

View File

@ -20,7 +20,6 @@ namespace WatchFace.Parser.Elements.TimeElements
[ParameterId(5)]
public long PmY { get; set; }
[ParameterId(6)]
[ParameterImageIndex]
public long ImageIndexPm { get; set; }

View File

@ -3,7 +3,7 @@ using WatchFace.Parser.Interfaces;
namespace WatchFace.Parser.Models.Elements
{
public class CaloriesElement : NumberElement, IDrawable
public class CaloriesElement : CompositeNumberElement, IDrawable
{
public CaloriesElement(Parameter parameter, Element parent, string name = null) :
base(parameter, parent, name) { }

View File

@ -13,7 +13,6 @@ namespace WatchFace.Parser.Models.Elements
public long KilometerImageIndex { get; set; }
public long DecimalPointImageIndex { get; set; }
public void Draw(Graphics drawer, Bitmap[] resources, WatchState state)
{
var kilometers = state.Distance / 1000;
@ -22,7 +21,8 @@ namespace WatchFace.Parser.Models.Elements
var images = Number.GetImagesForNumber(resources, kilometers);
images.Add(resources[DecimalPointImageIndex]);
images.AddRange(Number.GetImagesForNumber(resources, decimals));
images.Add(resources[KilometerImageIndex]);
if (KilometerImageIndex != DecimalPointImageIndex)
images.Add(resources[KilometerImageIndex]);
DrawerHelper.DrawImages(drawer, images, (int) Number.Spacing, Number.Alignment, Number.GetBox());
}

View File

@ -1,17 +1,17 @@
using System.Drawing;
using WatchFace.Parser.Helpers;
using WatchFace.Parser.Interfaces;
namespace WatchFace.Parser.Models.Elements
{
public class PulseElement : NumberElement, IDrawable
public class PulseElement : CompositeNumberElement, IDrawable
{
public PulseElement(Parameter parameter, Element parent, string name = null) :
base(parameter, parent, name) { }
public void Draw(Graphics drawer, Bitmap[] resources, WatchState state)
{
if (state.Pulse != null)
Draw(drawer, resources, state.Pulse.Value);
Draw(drawer, resources, state.Pulse);
}
}
}

View File

@ -3,7 +3,7 @@ using WatchFace.Parser.Interfaces;
namespace WatchFace.Parser.Models.Elements
{
public class StepsElement : NumberElement, IDrawable
public class StepsElement : CompositeNumberElement, IDrawable
{
public StepsElement(Parameter parameter, Element parent, string name = null) :
base(parameter, parent, name) { }

View File

@ -3,7 +3,7 @@ using WatchFace.Parser.Interfaces;
namespace WatchFace.Parser.Models.Elements
{
public class StepsGoalElement : NumberElement, IDrawable
public class StepsGoalElement : CompositeNumberElement, IDrawable
{
public StepsGoalElement(Parameter parameter, Element parent, string name = null) :
base(parameter, parent, name) { }

View File

@ -0,0 +1,52 @@
using System;
using System.Drawing;
using WatchFace.Parser.Models.Elements.AnalogDial;
namespace WatchFace.Parser.Models.Elements
{
public class AnalogDialBitmapElement : ContainerElement
{
public AnalogDialBitmapElement(Parameter parameter, Element parent = null, string name = null) :
base(parameter, parent, name) { }
public RectangleElement RedrawArea { get; set; }
public ImageElement Hours { get; set; }
public ImageElement Minutes { get; set; }
public ImageElement Seconds { get; set; }
public ImageElement CenterImage { get; set; }
private CoordinatesElement Center { get; set; }
private Point RotatePoint(CoordinatesElement element, double degrees)
{
var radians = degrees / 180 * Math.PI;
var x = element.X * Math.Cos(radians) + element.Y * Math.Sin(radians);
var y = element.X * Math.Sin(radians) - element.Y * Math.Cos(radians);
return new Point((int)Math.Floor(x + Center.X), (int)Math.Floor(y + Center.Y));
}
protected override Element CreateChildForParameter(Parameter parameter)
{
switch (parameter.Id)
{
case 1:
RedrawArea = new RectangleElement(parameter, this, nameof(Hours));
return RedrawArea;
case 2:
Hours = new ImageElement(parameter, this, nameof(Hours));
return Hours;
case 3:
Minutes = new ImageElement(parameter, this, nameof(Minutes));
return Minutes;
case 4:
Seconds = new ImageElement(parameter, this, nameof(Seconds));
return Seconds;
case 5:
CenterImage = new ImageElement(parameter, this, nameof(Seconds));
return CenterImage;
default:
return base.CreateChildForParameter(parameter);
}
}
}
}

View File

@ -9,8 +9,15 @@ namespace WatchFace.Parser.Models.Elements.Battery
public override void Draw(Graphics drawer, Bitmap[] resources, WatchState state)
{
var imageIndex = state.BatteryLevel * (int) ImagesCount / 100;
Draw(drawer, resources, imageIndex);
if (ImagesCount == 1)
{
if (state.BatteryLevel <= 10) Draw(drawer, resources, 0);
}
else
{
var imageIndex = state.BatteryLevel * (int) ImagesCount / 100;
Draw(drawer, resources, imageIndex);
}
}
}
}

View File

@ -3,7 +3,7 @@ using WatchFace.Parser.Interfaces;
namespace WatchFace.Parser.Models.Elements.Battery
{
public class BatteryNumberElement : NumberElement, IDrawable
public class BatteryNumberElement : CompositeNumberElement, IDrawable
{
public BatteryNumberElement(Parameter parameter, Element parent, string name = null) :
base(parameter, parent, name) { }

View File

@ -0,0 +1,56 @@
using System.Collections.Generic;
using System.Drawing;
using WatchFace.Parser.Helpers;
namespace WatchFace.Parser.Models.Elements
{
public class CompositeNumberElement : CompositeElement
{
public CompositeNumberElement(Parameter parameter, Element parent, string name = null) :
base(parameter, parent, name) { }
public NumberElement Number { get; set; }
public long? PrefixImageIndex { get; set; }
public long? EmptyImageIndex { get; set; }
public long? SuffixImageIndex { get; set; }
public void Draw(Graphics drawer, Bitmap[] resources, int? value)
{
var images = new List<Bitmap>();
if (PrefixImageIndex != null)
images.Add(resources[PrefixImageIndex.Value]);
if (value == null)
{
if (EmptyImageIndex != null) images.Add(resources[EmptyImageIndex.Value]);
}
else
images.AddRange(Number.GetImagesForNumber(resources, value.Value));
if (SuffixImageIndex != null)
images.Add(resources[SuffixImageIndex.Value]);
DrawerHelper.DrawImages(drawer, images, (int)Number.Spacing, Number.Alignment, Number.GetBox());
}
protected override Element CreateChildForParameter(Parameter parameter)
{
switch (parameter.Id)
{
case 1:
Number = new NumberElement(parameter, this, nameof(Number));
return Number;
case 2:
PrefixImageIndex = parameter.Value;
return new ValueElement(parameter, this, nameof(PrefixImageIndex));
case 3:
EmptyImageIndex = parameter.Value;
return new ValueElement(parameter, this, nameof(EmptyImageIndex));
case 4:
SuffixImageIndex = parameter.Value;
return new ValueElement(parameter, this, nameof(SuffixImageIndex));
default:
return base.CreateChildForParameter(parameter);
}
}
}
}

View File

@ -5,28 +5,16 @@ using WatchFace.Parser.Helpers;
namespace WatchFace.Parser.Models.Elements
{
public class NumberElement : CoordinatesElement
public class NumberElement : RectangleElement
{
public NumberElement(Parameter parameter, Element parent, string name = null) :
base(parameter, parent, name) { }
public long BottomRightX { get; set; }
public long BottomRightY { get; set; }
public TextAlignment Alignment { get; set; }
public long Spacing { get; set; }
public long ImageIndex { get; set; }
public long ImagesCount { get; set; }
public Rectangle GetBox()
{
return new Rectangle((int) X, (int) Y, (int) (BottomRightX - X), (int) (BottomRightY - Y));
}
public Rectangle GetAltBox(CoordinatesElement altCoordinates)
{
return new Rectangle((int) altCoordinates.X, (int) altCoordinates.Y, (int) (BottomRightX - X), (int) (BottomRightY - Y));
}
public void Draw(Graphics drawer, Bitmap[] images, int number, int minimumDigits = 1)
{
DrawerHelper.DrawImages(drawer, GetImagesForNumber(images, number, minimumDigits), (int) Spacing, Alignment, GetBox());
@ -47,12 +35,6 @@ namespace WatchFace.Parser.Models.Elements
{
switch (parameter.Id)
{
case 3:
BottomRightX = parameter.Value;
return new ValueElement(parameter, this, nameof(BottomRightX));
case 4:
BottomRightY = parameter.Value;
return new ValueElement(parameter, this, nameof(BottomRightY));
case 5:
Alignment = (TextAlignment) parameter.Value;
return new ValueElement(parameter, this, nameof(Alignment));

View File

@ -0,0 +1,38 @@
using System.Drawing;
namespace WatchFace.Parser.Models.Elements
{
public class RectangleElement : CoordinatesElement
{
public RectangleElement(Parameter parameter, Element parent, string name = null) :
base(parameter, parent, name) { }
public long BottomRightX { get; set; }
public long BottomRightY { get; set; }
public Rectangle GetBox()
{
return new Rectangle((int) X, (int) Y, (int) (BottomRightX - X), (int) (BottomRightY - Y));
}
public Rectangle GetAltBox(CoordinatesElement altCoordinates)
{
return new Rectangle((int) altCoordinates.X, (int) altCoordinates.Y, (int) (BottomRightX - X), (int) (BottomRightY - Y));
}
protected override Element CreateChildForParameter(Parameter parameter)
{
switch (parameter.Id)
{
case 3:
BottomRightX = parameter.Value;
return new ValueElement(parameter, this, nameof(BottomRightX));
case 4:
BottomRightY = parameter.Value;
return new ValueElement(parameter, this, nameof(BottomRightY));
default:
return base.CreateChildForParameter(parameter);
}
}
}
}

View File

@ -7,12 +7,16 @@ namespace WatchFace.Parser.Models.Elements
{
public AmPmElement(Parameter parameter, Element parent, string name) : base(parameter, parent, name) { }
public long ImageIndexAm { get; set; }
public long PmX { get; set; }
public long PmY { get; set; }
public long ImageIndexPm { get; set; }
public void Draw(Graphics drawer, Bitmap[] resources, WatchState state)
{
var imageIndex = state.Time.Hour < 12 ? ImageIndexAm : ImageIndexPm;
drawer.DrawImage(resources[imageIndex], new Point((int) X, (int) Y));
if (state.Time.Hour < 12)
drawer.DrawImage(resources[ImageIndexAm], new Point((int)X, (int)Y));
else
drawer.DrawImage(resources[ImageIndexPm], new Point((int)PmX, (int)PmY));
}
protected override Element CreateChildForParameter(Parameter parameter)
@ -23,6 +27,12 @@ namespace WatchFace.Parser.Models.Elements
ImageIndexAm = parameter.Value;
return new ValueElement(parameter, this, nameof(ImageIndexAm));
case 4:
PmX = parameter.Value;
return new ValueElement(parameter, this, nameof(PmX));
case 5:
PmY = parameter.Value;
return new ValueElement(parameter, this, nameof(PmY));
case 6:
ImageIndexPm = parameter.Value;
return new ValueElement(parameter, this, nameof(ImageIndexPm));
default:

View File

@ -18,6 +18,8 @@ namespace WatchFace.Parser.Models.Elements
{
var useAltCoordinates = CurrentAlt != null && state.CurrentTemperature == null;
var iconCoordinates = useAltCoordinates ? CurrentAlt : Current;
if (iconCoordinates != null)
drawer.DrawImage(LoadWeatherImage(state.CurrentWeather), iconCoordinates.X, iconCoordinates.Y);
if (iconCoordinates != null)
drawer.DrawImage(LoadWeatherImage(state.CurrentWeather), iconCoordinates.X, iconCoordinates.Y);

View File

@ -23,7 +23,10 @@ namespace WatchFace.Parser
var num = i + 1;
watchState.BatteryLevel = num * 10;
watchState.Pulse = 60 + num * 2;
if (i < 2)
watchState.Pulse = null;
else
watchState.Pulse = 65 + num * 2;
watchState.Steps = num * 1000;
watchState.Calories = num * 75;
watchState.Distance = num * 700;

View File

@ -51,13 +51,14 @@
</ItemGroup>
<ItemGroup>
<Compile Include="Elements\Activity.cs" />
<Compile Include="Elements\ActivityElements\CompositeNumber.cs" />
<Compile Include="Elements\ActivityElements\FormattedNumber.cs" />
<Compile Include="Elements\AnalogDialFace.cs" />
<Compile Include="Elements\AnalogDialVector.cs" />
<Compile Include="Elements\Background.cs" />
<Compile Include="Elements\BasicElements\CircleScale.cs" />
<Compile Include="Elements\AnalogDialFaceElements\ClockHand.cs" />
<Compile Include="Elements\BasicElements\Coordinates.cs" />
<Compile Include="Elements\BasicElements\UnknownBlock.cs" />
<Compile Include="Elements\BasicElements\Rectangle.cs" />
<Compile Include="Elements\BasicElements\Image.cs" />
<Compile Include="Elements\BasicElements\ImageSet.cs" />
<Compile Include="Elements\BasicElements\Number.cs" />
@ -70,13 +71,14 @@
<Compile Include="Elements\StepsProgress.cs" />
<Compile Include="Elements\Status.cs" />
<Compile Include="Elements\StatusElements\Switch.cs" />
<Compile Include="Elements\Unknown12.cs" />
<Compile Include="Elements\PulseProgress.cs" />
<Compile Include="Elements\AnalogDialBitmaps.cs" />
<Compile Include="Elements\Time.cs" />
<Compile Include="Elements\TimeElements\AmPm.cs" />
<Compile Include="Elements\TimeElements\TwoDigits.cs" />
<Compile Include="Elements\Weather.cs" />
<Compile Include="Elements\WeatherElements\CustomWeatherIcon.cs" />
<Compile Include="Elements\WeatherElements\AirPollution.cs" />
<Compile Include="Elements\WeatherElements\CustomWeatherIcon.cs" />
<Compile Include="Elements\WeatherElements\OneLineTemperature.cs" />
<Compile Include="Elements\WeatherElements\SeparateTemperature.cs" />
<Compile Include="Elements\WeatherElements\Temperature.cs" />
@ -92,15 +94,18 @@
<Compile Include="Models\Elements\Activity\StepsElement.cs" />
<Compile Include="Models\Elements\Activity\StepsGoalElement.cs" />
<Compile Include="Models\Elements\Activity\PulseElement.cs" />
<Compile Include="Models\Elements\AnalogDialBitmapElement.cs" />
<Compile Include="Models\Elements\AnalogDial\SecondsClockHandElement.cs" />
<Compile Include="Models\Elements\AnalogDial\MinutesClockHandElement.cs" />
<Compile Include="Models\Elements\AnalogDial\HoursClockHandElement.cs" />
<Compile Include="Models\Elements\Basic\ContainerElement.cs" />
<Compile Include="Models\Elements\Battery\BatteryLenearProgressElement.cs" />
<Compile Include="Models\Elements\Battery\BatteryNumberElement.cs" />
<Compile Include="Models\Elements\Common\CompositeNumberElement.cs" />
<Compile Include="Models\Elements\Common\ImageSetElement.cs" />
<Compile Include="Models\Elements\Common\CircularProgressElement.cs" />
<Compile Include="Models\Elements\Common\ClockHandElement.cs" />
<Compile Include="Models\Elements\Common\RectangleElement.cs" />
<Compile Include="Models\Elements\GoalProgressElement.cs" />
<Compile Include="Models\Elements\GoalProgress\GoalReachedElement.cs" />
<Compile Include="Models\Elements\Common\LinearProgressElement.cs" />

View File

@ -30,9 +30,12 @@ namespace WatchFace.Parser
public Battery Battery { get; set; }
[ParameterId(10)]
public AnalogDialFace AnalogDialFace { get; set; }
public AnalogDialVector AnalogDialFace { get; set; }
[ParameterId(12)]
public Unknown12 Unknown12 { get; set; }
public AnalogDialBitmaps AnalogDialBitmaps { get; set; }
[ParameterId(13)]
public PulseProgress PulseProgress { get; set; }
}
}