Fixed invalid colors on unpacking 16bit images, added support for new WF elements
parent
237308699a
commit
d48bc3d81c
|
@ -118,11 +118,11 @@ namespace Resources.Image
|
|||
var bitReader = new BitReader(rowBytes);
|
||||
for (var x = 0; x < _width; x++)
|
||||
{
|
||||
var firstByte = bitReader.ReadByte();
|
||||
var secondByte = bitReader.ReadByte();
|
||||
var b = ((secondByte >> 3) & 0x1f) << 3;
|
||||
var g = ((secondByte & (0x07 << 2)) | (firstByte & (0x40 >> 5))) << 3;
|
||||
var r = (firstByte & 0x1f) << 3;
|
||||
var firstByte = (int)bitReader.ReadByte();
|
||||
var secondByte = (int)bitReader.ReadByte();
|
||||
var b = (byte)(secondByte >> 3 & 0x1f) << 3;
|
||||
var g = (byte)(((firstByte >> 5) & 0x7) | ((secondByte & 0x07) << 3)) << 2;
|
||||
var r = (byte)(firstByte & 0x1f) << 3;
|
||||
var color = Color.FromArgb(0xff, r, g, b);
|
||||
context.SetPixel(x, y, color);
|
||||
}
|
||||
|
|
|
@ -19,6 +19,9 @@ namespace WatchFace.Parser.Elements
|
|||
public CompositeNumber Pulse { get; set; }
|
||||
|
||||
[ParameterId(5)]
|
||||
public FormattedNumber Distance { get; set; }
|
||||
public DistanceNumber Distance { get; set; }
|
||||
|
||||
[ParameterId(6)]
|
||||
public StepsWithGoalNumber StepsWithGoal { get; set; }
|
||||
}
|
||||
}
|
|
@ -3,7 +3,7 @@ using WatchFace.Parser.Elements.BasicElements;
|
|||
|
||||
namespace WatchFace.Parser.Elements.ActivityElements
|
||||
{
|
||||
public class FormattedNumber
|
||||
public class DistanceNumber
|
||||
{
|
||||
[ParameterId(1)]
|
||||
public Number Number { get; set; }
|
|
@ -0,0 +1,15 @@
|
|||
using WatchFace.Parser.Attributes;
|
||||
using WatchFace.Parser.Elements.BasicElements;
|
||||
|
||||
namespace WatchFace.Parser.Elements.ActivityElements
|
||||
{
|
||||
public class StepsWithGoalNumber
|
||||
{
|
||||
[ParameterId(1)]
|
||||
public Number Number { get; set; }
|
||||
|
||||
[ParameterId(2)]
|
||||
[ParameterImageIndex]
|
||||
public long? DelimiterImageIndex { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,12 +1,13 @@
|
|||
using WatchFace.Parser.Attributes;
|
||||
using WatchFace.Parser.Elements.BasicElements;
|
||||
using WatchFace.Parser.Elements.BatteryElements;
|
||||
|
||||
namespace WatchFace.Parser.Elements
|
||||
{
|
||||
public class Battery
|
||||
{
|
||||
[ParameterId(1)]
|
||||
public CompositeNumber Text { get; set; }
|
||||
public BatteryNumber Text { get; set; }
|
||||
|
||||
[ParameterId(2)]
|
||||
public ImageSet Icon { get; set; }
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
using WatchFace.Parser.Attributes;
|
||||
using WatchFace.Parser.Elements.BasicElements;
|
||||
|
||||
namespace WatchFace.Parser.Elements.BatteryElements
|
||||
{
|
||||
public class BatteryNumber
|
||||
{
|
||||
[ParameterId(1)]
|
||||
public Number Number { get; set; }
|
||||
|
||||
[ParameterId(2)]
|
||||
[ParameterImageIndex]
|
||||
public CircleScale CircleScale { get; set; }
|
||||
|
||||
[ParameterId(3)]
|
||||
[ParameterImageIndex]
|
||||
public long? PrefixImageIndex { get; set; }
|
||||
|
||||
[ParameterId(4)]
|
||||
[ParameterImageIndex]
|
||||
public long? SuffixImageIndex { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using WatchFace.Parser.Helpers;
|
||||
using WatchFace.Parser.Interfaces;
|
||||
|
||||
namespace WatchFace.Parser.Models.Elements.Activity
|
||||
{
|
||||
public class StepsWithGoalElement : CompositeElement, IDrawable
|
||||
{
|
||||
public StepsWithGoalElement(Parameter parameter, Element parent, string name = null) :
|
||||
base(parameter, parent, name) { }
|
||||
|
||||
public NumberElement Number { get; set; }
|
||||
public long DelimiterImageIndex { get; set; }
|
||||
|
||||
public void Draw(Graphics drawer, Bitmap[] resources, WatchState state)
|
||||
{
|
||||
var images = new List<Bitmap>();
|
||||
images.AddRange(Number.GetImagesForNumber(resources, state.Steps));
|
||||
images.Add(resources[DelimiterImageIndex]);
|
||||
images.AddRange(Number.GetImagesForNumber(resources, state.Goal));
|
||||
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:
|
||||
DelimiterImageIndex = parameter.Value;
|
||||
return new ValueElement(parameter, this, nameof(DelimiterImageIndex));
|
||||
default:
|
||||
return base.CreateChildForParameter(parameter);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,6 @@
|
|||
namespace WatchFace.Parser.Models.Elements
|
||||
using WatchFace.Parser.Models.Elements.Activity;
|
||||
|
||||
namespace WatchFace.Parser.Models.Elements
|
||||
{
|
||||
public class ActivityElement : ContainerElement
|
||||
{
|
||||
|
@ -10,6 +12,7 @@
|
|||
public CaloriesElement Calories { get; set; }
|
||||
public PulseElement Pulse { get; set; }
|
||||
public DistanceElement Distance { get; set; }
|
||||
public StepsWithGoalElement StepsWithGoal { get; set; }
|
||||
|
||||
protected override Element CreateChildForParameter(Parameter parameter)
|
||||
{
|
||||
|
@ -30,6 +33,9 @@
|
|||
case 5:
|
||||
Distance = new DistanceElement(parameter, this);
|
||||
return Distance;
|
||||
case 6:
|
||||
StepsWithGoal = new StepsWithGoalElement(parameter, this);
|
||||
return StepsWithGoal;
|
||||
default:
|
||||
return base.CreateChildForParameter(parameter);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
using System;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.Drawing;
|
||||
using BumpKit;
|
||||
using WatchFace.Parser.Interfaces;
|
||||
|
||||
|
@ -32,22 +30,23 @@ namespace WatchFace.Parser.Models.Elements
|
|||
{
|
||||
var angle = DegreeFromValues(state.Time.Minute, 60);
|
||||
var hoursImage = RotateImage(
|
||||
resources[Minutes.ImageIndex], new Point((int)Minutes.X, (int)Minutes.Y), angle
|
||||
resources[Minutes.ImageIndex], new Point((int) Minutes.X, (int) Minutes.Y), angle
|
||||
);
|
||||
drawer.DrawImage(hoursImage, new Point((int)RedrawArea.X, (int)RedrawArea.Y));
|
||||
drawer.DrawImage(hoursImage, new Point((int) RedrawArea.X, (int) RedrawArea.Y));
|
||||
}
|
||||
|
||||
if (Seconds != null)
|
||||
{
|
||||
var angle = DegreeFromValues(state.Time.Second, 60);
|
||||
var hoursImage = RotateImage(
|
||||
resources[Seconds.ImageIndex], new Point((int)Seconds.X, (int)Seconds.Y), angle
|
||||
resources[Seconds.ImageIndex], new Point((int) Seconds.X, (int) Seconds.Y), angle
|
||||
);
|
||||
drawer.DrawImage(hoursImage, new Point((int)RedrawArea.X, (int)RedrawArea.Y));
|
||||
drawer.DrawImage(hoursImage, new Point((int) RedrawArea.X, (int) RedrawArea.Y));
|
||||
}
|
||||
|
||||
if (CenterImage != null)
|
||||
drawer.DrawImage(resources[CenterImage.ImageIndex], new Point((int)CenterImage.X, (int)CenterImage.Y));
|
||||
drawer.DrawImage(resources[CenterImage.ImageIndex],
|
||||
new Point((int) CenterImage.X, (int) CenterImage.Y));
|
||||
}
|
||||
|
||||
private static double DegreeFromValues(double value, double total)
|
||||
|
@ -55,24 +54,19 @@ namespace WatchFace.Parser.Models.Elements
|
|||
return value * 360 / total - 90;
|
||||
}
|
||||
|
||||
private Bitmap RotateImage(Image image, Point ImageCoords, double degrees)
|
||||
private Bitmap RotateImage(Image image, Point imageCoords, double degrees)
|
||||
{
|
||||
var radians = degrees / 180 * Math.PI;
|
||||
var sin = Math.Sin(radians);
|
||||
var cos = Math.Cos(radians);
|
||||
|
||||
var drawBox = RedrawArea.GetBox();
|
||||
var newImage = new Bitmap(drawBox.Width, drawBox.Height);
|
||||
using (var graphics = Graphics.FromImage(newImage))
|
||||
{
|
||||
graphics.DrawImage(image, new Point(ImageCoords.X - drawBox.X, ImageCoords.Y - drawBox.Y));
|
||||
graphics.DrawImage(image, new Point(imageCoords.X - drawBox.X, imageCoords.Y - drawBox.Y));
|
||||
}
|
||||
|
||||
while (degrees < 0) degrees += 360;
|
||||
while (degrees > 360) degrees -= 360;
|
||||
var rotated = newImage.Rotate(degrees);
|
||||
rotated.Save("tmp.png");
|
||||
return rotated as Bitmap;
|
||||
return rotated as Bitmap;
|
||||
}
|
||||
|
||||
protected override Element CreateChildForParameter(Parameter parameter)
|
||||
|
|
|
@ -1,16 +1,55 @@
|
|||
using System.Drawing;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using WatchFace.Parser.Helpers;
|
||||
using WatchFace.Parser.Interfaces;
|
||||
using WatchFace.Parser.Models.Elements.Common;
|
||||
|
||||
namespace WatchFace.Parser.Models.Elements.Battery
|
||||
{
|
||||
public class BatteryNumberElement : CompositeNumberElement, IDrawable
|
||||
public class BatteryNumberElement : CompositeElement, IDrawable
|
||||
{
|
||||
public BatteryNumberElement(Parameter parameter, Element parent, string name = null) :
|
||||
base(parameter, parent, name) { }
|
||||
|
||||
|
||||
public NumberElement Number { get; set; }
|
||||
public CircularProgressElement CircularProgress { get; set; }
|
||||
public long? PrefixImageIndex { get; set; }
|
||||
public long? SuffixImageIndex { get; set; }
|
||||
|
||||
public void Draw(Graphics drawer, Bitmap[] resources, WatchState state)
|
||||
{
|
||||
Draw(drawer, resources, state.BatteryLevel);
|
||||
var images = new List<Bitmap>();
|
||||
if (PrefixImageIndex != null)
|
||||
images.Add(resources[PrefixImageIndex.Value]);
|
||||
images.AddRange(Number.GetImagesForNumber(resources, state.BatteryLevel));
|
||||
if (SuffixImageIndex != null)
|
||||
images.Add(resources[SuffixImageIndex.Value]);
|
||||
|
||||
DrawerHelper.DrawImages(drawer, images, (int)Number.Spacing, Number.Alignment, Number.GetBox());
|
||||
|
||||
CircularProgress?.Draw(drawer, resources, state);
|
||||
}
|
||||
|
||||
protected override Element CreateChildForParameter(Parameter parameter)
|
||||
{
|
||||
switch (parameter.Id)
|
||||
{
|
||||
case 1:
|
||||
Number = new NumberElement(parameter, this, nameof(Number));
|
||||
return Number;
|
||||
case 2:
|
||||
CircularProgress = new CircularBatteryProgressElement(parameter, this);
|
||||
return CircularProgress;
|
||||
case 3:
|
||||
PrefixImageIndex = parameter.Value;
|
||||
return new ValueElement(parameter, this, nameof(PrefixImageIndex));
|
||||
case 4:
|
||||
SuffixImageIndex = parameter.Value;
|
||||
return new ValueElement(parameter, this, nameof(SuffixImageIndex));
|
||||
default:
|
||||
return base.CreateChildForParameter(parameter);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
using System.Drawing;
|
||||
using WatchFace.Parser.Models.Elements.Common;
|
||||
|
||||
namespace WatchFace.Parser.Models.Elements.Battery
|
||||
{
|
||||
public class CircularBatteryProgressElement : CircularProgressElement
|
||||
{
|
||||
public CircularBatteryProgressElement(Parameter parameter, Element parent, string name = null) :
|
||||
base(parameter, parent, name) { }
|
||||
|
||||
public override void Draw(Graphics drawer, Bitmap[] resources, WatchState state)
|
||||
{
|
||||
Draw(drawer, resources, state.BatteryLevel, 100);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
using System.Drawing;
|
||||
using WatchFace.Parser.Interfaces;
|
||||
|
||||
namespace WatchFace.Parser.Models.Elements.GoalProgress
|
||||
namespace WatchFace.Parser.Models.Elements.Common
|
||||
{
|
||||
public abstract class CircularProgressElement : CoordinatesElement, IDrawable
|
||||
{
|
||||
|
@ -19,7 +19,8 @@ namespace WatchFace.Parser.Models.Elements.GoalProgress
|
|||
|
||||
public void Draw(Graphics drawer, Bitmap[] resources, int value, int total)
|
||||
{
|
||||
var sectorAngle = (EndAngle - StartAngle) * value / total;
|
||||
var part = value >= total ? 1.0f : (float) value / total;
|
||||
var sectorAngle = (EndAngle - StartAngle) * part;
|
||||
var pen = new Pen(Color, Width);
|
||||
var rect = new Rectangle((int) (X - RadiusX), (int) (Y - RadiusY),
|
||||
(int) (RadiusX * 2), (int) (RadiusY * 2));
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System.Drawing;
|
||||
using WatchFace.Parser.Models.Elements.Common;
|
||||
|
||||
namespace WatchFace.Parser.Models.Elements.GoalProgress
|
||||
{
|
||||
|
|
|
@ -51,8 +51,9 @@
|
|||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Elements\Activity.cs" />
|
||||
<Compile Include="Elements\ActivityElements\StepsWithGoalNumber.cs" />
|
||||
<Compile Include="Elements\BasicElements\CompositeNumber.cs" />
|
||||
<Compile Include="Elements\ActivityElements\FormattedNumber.cs" />
|
||||
<Compile Include="Elements\ActivityElements\DistanceNumber.cs" />
|
||||
<Compile Include="Elements\AnalogDialVector.cs" />
|
||||
<Compile Include="Elements\Background.cs" />
|
||||
<Compile Include="Elements\BasicElements\CircleScale.cs" />
|
||||
|
@ -64,6 +65,7 @@
|
|||
<Compile Include="Elements\BasicElements\Number.cs" />
|
||||
<Compile Include="Elements\BasicElements\Scale.cs" />
|
||||
<Compile Include="Elements\Battery.cs" />
|
||||
<Compile Include="Elements\BatteryElements\BatteryNumber.cs" />
|
||||
<Compile Include="Elements\Date.cs" />
|
||||
<Compile Include="Elements\DateElements\MonthAndDay.cs" />
|
||||
<Compile Include="Elements\DateElements\OneLineMonthAndDay.cs" />
|
||||
|
@ -91,6 +93,7 @@
|
|||
<Compile Include="JsonConverters\ColorJsonConverter.cs" />
|
||||
<Compile Include="Models\DrawingOrderPosition.cs" />
|
||||
<Compile Include="Models\Elements\Activity\CaloriesElement.cs" />
|
||||
<Compile Include="Models\Elements\Activity\StepsWithGoalElement.cs" />
|
||||
<Compile Include="Models\Elements\Activity\StepsElement.cs" />
|
||||
<Compile Include="Models\Elements\Activity\StepsGoalElement.cs" />
|
||||
<Compile Include="Models\Elements\Activity\PulseElement.cs" />
|
||||
|
@ -101,6 +104,7 @@
|
|||
<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\Battery\CircularBatteryProgressElement.cs" />
|
||||
<Compile Include="Models\Elements\Common\CompositeNumberElement.cs" />
|
||||
<Compile Include="Models\Elements\Common\ImageSetElement.cs" />
|
||||
<Compile Include="Models\Elements\Common\CircularProgressElement.cs" />
|
||||
|
|
Loading…
Reference in New Issue