Add extension source
This commit is contained in:
parent
9469f5432f
commit
76ce3161ec
|
@ -0,0 +1,75 @@
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using SixLabors.Fonts;
|
||||||
|
using SixLabors.ImageSharp.PixelFormats;
|
||||||
|
namespace ClockExtension
|
||||||
|
{
|
||||||
|
public class ClockData
|
||||||
|
{
|
||||||
|
public static ClockData Load(string extDir,FontCollection coll)
|
||||||
|
{
|
||||||
|
string fontDir = Path.Combine(extDir,"Fonts");
|
||||||
|
if(Directory.Exists(fontDir)){
|
||||||
|
foreach(var ttf in Directory.GetFiles(fontDir,"*.ttf"))
|
||||||
|
{
|
||||||
|
coll.Add(ttf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
string extInfoFile=Path.Combine(extDir,"ext_info.json");
|
||||||
|
if(File.Exists(extInfoFile))
|
||||||
|
{
|
||||||
|
|
||||||
|
string extInfoFileString = File.ReadAllText(extInfoFile);
|
||||||
|
var cd=JsonConvert.DeserializeObject<ClockData>(extInfoFileString);
|
||||||
|
if(cd != null)
|
||||||
|
{
|
||||||
|
cd.FilePath = extInfoFile;
|
||||||
|
FontFamily[] fam = coll.Families.ToArray();
|
||||||
|
for(int i = 0;i<fam.Length;i++)
|
||||||
|
{
|
||||||
|
if(fam[i].Name.Equals(cd.FontName,StringComparison.Ordinal))
|
||||||
|
{
|
||||||
|
cd.FontIndex=i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return cd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new ClockData {FilePath=extInfoFile};
|
||||||
|
}
|
||||||
|
public ClockData()
|
||||||
|
{
|
||||||
|
EnableClock=true;
|
||||||
|
DateFormat = "yyyy/MM/dd HH:mm:ss";
|
||||||
|
FontIndex=0;
|
||||||
|
FilePath="";
|
||||||
|
FontSize = 24;
|
||||||
|
ForeColor=Eto.Drawing.Colors.White;
|
||||||
|
X=16;
|
||||||
|
Y=16;
|
||||||
|
}
|
||||||
|
[JsonIgnore]
|
||||||
|
public int FontIndex {get;set;}
|
||||||
|
[JsonIgnore]
|
||||||
|
public string FilePath {get;private set;}
|
||||||
|
public bool EnableClock {get;set;}
|
||||||
|
|
||||||
|
public int X {get;set;}
|
||||||
|
public int Y {get;set;}
|
||||||
|
|
||||||
|
public string? FontName {get;set;}
|
||||||
|
|
||||||
|
public float FontSize {get;set;}
|
||||||
|
|
||||||
|
public string DateFormat {get;set;}
|
||||||
|
|
||||||
|
public Rgb ForeColor {get;set;}
|
||||||
|
|
||||||
|
public void Save()
|
||||||
|
{
|
||||||
|
string data=JsonConvert.SerializeObject(this);
|
||||||
|
File.WriteAllText(FilePath,data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,154 @@
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using Eto.Forms;
|
||||||
|
using SixLabors.Fonts;
|
||||||
|
|
||||||
|
namespace ClockExtension
|
||||||
|
{
|
||||||
|
public class ClockDialog : Dialog
|
||||||
|
{
|
||||||
|
public ClockDialog(ClockData data,FontCollection collection,string extPath)
|
||||||
|
{
|
||||||
|
Button changeColor = new Button {Text="Change Color"};
|
||||||
|
changeColor.Click+=(sender,e)=>{
|
||||||
|
using(var ccd = new ColorDialog())
|
||||||
|
{
|
||||||
|
ccd.Color = data.ForeColor;
|
||||||
|
ccd.ColorChanged+=(sender,e)=>{
|
||||||
|
data.ForeColor=ccd.Color;
|
||||||
|
};
|
||||||
|
ccd.ShowDialog(this);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Button saveBtn = new Button {Text="Save"};
|
||||||
|
saveBtn.Click +=(sender,e)=>{
|
||||||
|
data.Save();
|
||||||
|
this.Close();
|
||||||
|
};
|
||||||
|
CheckBox enabled=new CheckBox{Text="Enable Clock"};
|
||||||
|
enabled.Checked = data.EnableClock;
|
||||||
|
enabled.CheckedChanged+=(sender,e)=>{
|
||||||
|
data.EnableClock=enabled.Checked.GetValueOrDefault();
|
||||||
|
};
|
||||||
|
NumericStepper fontSize=new NumericStepper{MinValue=6,MaxValue=65535,Value = data.FontSize,DecimalPlaces=2};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
fontSize.ValueChanged+= (sender,e)=>{
|
||||||
|
data.FontSize = (float)fontSize.Value;
|
||||||
|
};
|
||||||
|
NumericStepper x=new NumericStepper {MinValue=0,MaxValue=65535,Value=data.X};
|
||||||
|
x.ValueChanged +=(sender,e)=>{
|
||||||
|
data.X=(int)x.Value;
|
||||||
|
};
|
||||||
|
NumericStepper y=new NumericStepper {MinValue=0,MaxValue=65535,Value=data.Y};
|
||||||
|
y.ValueChanged +=(sender,e)=>{
|
||||||
|
data.Y=(int)y.Value;
|
||||||
|
};
|
||||||
|
|
||||||
|
GroupBox gbox=new GroupBox{Text="Clock Position"};
|
||||||
|
DynamicLayout lytg=new DynamicLayout();
|
||||||
|
lytg.BeginVertical();
|
||||||
|
lytg.BeginHorizontal();
|
||||||
|
lytg.Add(x,true);
|
||||||
|
lytg.Add(y,true);
|
||||||
|
lytg.EndHorizontal();
|
||||||
|
lytg.EndVertical();
|
||||||
|
|
||||||
|
gbox.Content=lytg;
|
||||||
|
ObservableCollection<string> fonts = new ObservableCollection<string>();
|
||||||
|
Title="Clock Settings";
|
||||||
|
TextBox timeFormat=new TextBox();
|
||||||
|
timeFormat.PlaceholderText="yyyy/MM/dd HH:mm:ss";
|
||||||
|
timeFormat.Text=data.DateFormat;
|
||||||
|
timeFormat.TextChanged+=(sender,e)=>{
|
||||||
|
if(string.IsNullOrWhiteSpace(timeFormat.Text))
|
||||||
|
{
|
||||||
|
data.DateFormat=timeFormat.PlaceholderText;
|
||||||
|
}else{
|
||||||
|
data.DateFormat=timeFormat.Text;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
DropDown down = new DropDown();
|
||||||
|
down.Tag = data;
|
||||||
|
down.DataStore = fonts;
|
||||||
|
Button browseFont=new Button {Text="Add Font"};
|
||||||
|
browseFont.Click +=(sender,e)=>{
|
||||||
|
using(var ofd=new OpenFileDialog())
|
||||||
|
{
|
||||||
|
ofd.MultiSelect=true;
|
||||||
|
ofd.Filters.Add(new FileFilter("True Type Font",".ttf"));
|
||||||
|
if(ofd.ShowDialog(this)==DialogResult.Ok)
|
||||||
|
{
|
||||||
|
foreach(var fname in ofd.Filenames){
|
||||||
|
string fontDir = Path.Combine(extPath,"Fonts");
|
||||||
|
Directory.CreateDirectory(fontDir);
|
||||||
|
string fontPath=Path.Combine(fontDir,Path.GetFileName(fname));
|
||||||
|
File.Copy(fname,fontPath);
|
||||||
|
collection.Add(fontPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DropDownRefresh(collection,fonts,down);
|
||||||
|
};
|
||||||
|
DynamicLayout lyt=new DynamicLayout();
|
||||||
|
lyt.BeginVertical();
|
||||||
|
lyt.BeginHorizontal();
|
||||||
|
lyt.Add(enabled);
|
||||||
|
lyt.EndHorizontal();
|
||||||
|
lyt.EndBeginVertical();
|
||||||
|
lyt.BeginHorizontal();
|
||||||
|
lyt.Add(down,true);
|
||||||
|
DropDownRefresh(collection,fonts,down);
|
||||||
|
if(data.FontIndex < fonts.Count)
|
||||||
|
{
|
||||||
|
down.SelectedIndex=data.FontIndex;
|
||||||
|
}else{
|
||||||
|
down.SelectedIndex=0;
|
||||||
|
}
|
||||||
|
lyt.Add(fontSize);
|
||||||
|
lyt.Add(browseFont);
|
||||||
|
|
||||||
|
lyt.EndHorizontal();
|
||||||
|
lyt.EndBeginVertical();
|
||||||
|
lyt.BeginHorizontal();
|
||||||
|
lyt.Add(timeFormat,true);
|
||||||
|
lyt.EndHorizontal();
|
||||||
|
lyt.EndBeginVertical();
|
||||||
|
lyt.BeginHorizontal();
|
||||||
|
lyt.Add(gbox,true);
|
||||||
|
lyt.EndHorizontal();
|
||||||
|
lyt.EndBeginVertical();
|
||||||
|
lyt.BeginHorizontal();
|
||||||
|
lyt.Add(changeColor,true);
|
||||||
|
lyt.Add(saveBtn,true);
|
||||||
|
lyt.EndHorizontal();
|
||||||
|
lyt.EndVertical();
|
||||||
|
this.Content=lyt;
|
||||||
|
this.Resizable=true;
|
||||||
|
}
|
||||||
|
public void SelectFont(object? sender,EventArgs e)
|
||||||
|
{
|
||||||
|
if(sender ==null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var dd=(DropDown)sender;
|
||||||
|
var coll=(ObservableCollection<string>)dd.DataStore;
|
||||||
|
var selectedFont=(ClockData)dd.Tag;
|
||||||
|
if(dd.SelectedIndex > -1){
|
||||||
|
selectedFont.FontName = coll[dd.SelectedIndex];
|
||||||
|
selectedFont.FontIndex=dd.SelectedIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void DropDownRefresh(FontCollection collection,ObservableCollection<string> fonts,DropDown dd)
|
||||||
|
{
|
||||||
|
dd.SelectedIndexChanged-=SelectFont;
|
||||||
|
fonts.Clear();
|
||||||
|
foreach(var font in collection.Families)
|
||||||
|
{
|
||||||
|
fonts.Add(font.Name);
|
||||||
|
}
|
||||||
|
dd.SelectedIndexChanged+=SelectFont;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Library</OutputType>
|
||||||
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="SixLabors.Fonts" Version="1.0.0-beta17" />
|
||||||
|
<PackageReference Include="SixLabors.ImageSharp.Drawing" Version="1.0.0-beta14" />
|
||||||
|
<PackageReference Include="Tesses.TimelapseApi" Version="1.0.0" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
|
@ -0,0 +1,52 @@
|
||||||
|
using TimelapseApi;
|
||||||
|
using Eto.Forms;
|
||||||
|
using System;
|
||||||
|
using SixLabors.ImageSharp;
|
||||||
|
using SixLabors.ImageSharp.PixelFormats;
|
||||||
|
using SixLabors.ImageSharp.Processing;
|
||||||
|
using SixLabors.Fonts;
|
||||||
|
|
||||||
|
using SixLabors.ImageSharp.Drawing.Processing;
|
||||||
|
|
||||||
|
namespace ClockExtension
|
||||||
|
{
|
||||||
|
public class ClockExtension : TimelapseExtension
|
||||||
|
{
|
||||||
|
FontCollection collection = new FontCollection();
|
||||||
|
public ClockExtension()
|
||||||
|
{
|
||||||
|
collection.AddSystemFonts();
|
||||||
|
|
||||||
|
Data=new ClockData();
|
||||||
|
}
|
||||||
|
public ClockData Data {get;set;}
|
||||||
|
public override string Name => "Clock Extension";
|
||||||
|
public override Guid Id => Guid.Parse("{1cb8b576-e2e8-44d5-a8e1-e25a47eb0564}"); //https://duckduckgo.com/?q=guid&t=ffab&ia=answer
|
||||||
|
|
||||||
|
protected override void OnCreate(ExtensionFeatures features)
|
||||||
|
{
|
||||||
|
Data=ClockData.Load(GetExtensionFolder(),collection);
|
||||||
|
features.RegisterFrameHandler(ImageHandler,"Draw Clock").RegisterSettingsDialog(()=>{
|
||||||
|
return new ClockDialog(Data,collection,GetExtensionFolder());
|
||||||
|
},"Clock Settings");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private bool ImageHandler(Image<Rgb24> arg)
|
||||||
|
{
|
||||||
|
if(Data.EnableClock)
|
||||||
|
{
|
||||||
|
string nowTime=DateTime.Now.ToString(Data.DateFormat.Replace("\\n","\n"));
|
||||||
|
arg.Mutate((e)=>{
|
||||||
|
var font=collection.Families.Skip(Data.FontIndex).FirstOrDefault();
|
||||||
|
|
||||||
|
var f=font.CreateFont(Data.FontSize);
|
||||||
|
e.DrawText(nowTime,f,Data.ForeColor,new PointF(Data.X,Data.Y));
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
using TimelapseApi;
|
||||||
|
using Eto.Forms;
|
||||||
|
using System;
|
||||||
|
using SixLabors.ImageSharp;
|
||||||
|
using SixLabors.ImageSharp.PixelFormats;
|
||||||
|
using SixLabors.ImageSharp.Processing;
|
||||||
|
using SixLabors.Fonts;
|
||||||
|
namespace ClockExtension
|
||||||
|
{
|
||||||
|
public class Rgb
|
||||||
|
{
|
||||||
|
public byte Red {get;set;}
|
||||||
|
public byte Green {get;set;}
|
||||||
|
|
||||||
|
public byte Blue {get;set;}
|
||||||
|
|
||||||
|
public static implicit operator Rgb24(Rgb color)
|
||||||
|
{
|
||||||
|
return new Rgb24(color.Red,color.Green,color.Blue);
|
||||||
|
}
|
||||||
|
public static implicit operator Rgb(Color c)
|
||||||
|
{
|
||||||
|
return c.ToPixel<Rgb24>();
|
||||||
|
}
|
||||||
|
public static implicit operator Color(Rgb color)
|
||||||
|
{
|
||||||
|
return new Color(color);
|
||||||
|
}
|
||||||
|
public static implicit operator Rgb(Rgb24 color)
|
||||||
|
{
|
||||||
|
return new Rgb {Red=color.R,Green=color.G,Blue = color.B};
|
||||||
|
}
|
||||||
|
public static implicit operator Eto.Drawing.Color(Rgb color)
|
||||||
|
{
|
||||||
|
return new Eto.Drawing.Color((float)(color.Red/255.0),(float)(color.Green/255.0),(float)(color.Blue/255.0));
|
||||||
|
}
|
||||||
|
public static implicit operator Rgb(Eto.Drawing.Color color)
|
||||||
|
{
|
||||||
|
byte r=(byte)(color.R * 255);
|
||||||
|
byte g=(byte)(color.G * 255);
|
||||||
|
byte b=(byte)(color.B * 255);
|
||||||
|
return new Rgb{Red=r,Green=g,Blue=b};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"name": "Clock Extension",
|
||||||
|
"author": "Tesses",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "Draws clock on screen"
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
#!/bin/bash
|
||||||
|
timelapsepack install
|
||||||
|
cd ~/TimelapseNow/Timelapse.Linux
|
||||||
|
dotnet run
|
|
@ -0,0 +1,83 @@
|
||||||
|
using TimelapseApi;
|
||||||
|
using System;
|
||||||
|
using SixLabors.ImageSharp;
|
||||||
|
using SixLabors.ImageSharp.PixelFormats;
|
||||||
|
using SixLabors.ImageSharp.Processing;
|
||||||
|
using SixLabors.ImageSharp.Drawing;
|
||||||
|
using SixLabors.ImageSharp.Drawing.Processing;
|
||||||
|
|
||||||
|
namespace TestPattern
|
||||||
|
{
|
||||||
|
public class TestPattern : TimelapseExtension
|
||||||
|
{
|
||||||
|
public override string Name => "Test Pattern";
|
||||||
|
public override Guid Id => Guid.Parse("{d918ac89-c07a-4ce4-a94b-c3e6c6f7a7e3}"); //https://duckduckgo.com/?q=guid&t=ffab&ia=answer
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
protected override void OnCreate(ExtensionFeatures features)
|
||||||
|
{
|
||||||
|
|
||||||
|
features.RegisterFrameHandler((e)=>{
|
||||||
|
if(Instance == null)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if(Instance.HasCamera)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
int colW=e.Width / 7;
|
||||||
|
int widthtotalBottom = (int)(colW* 3.80);
|
||||||
|
int colH=(int)(e.Height * 0.70);
|
||||||
|
int bottomY=(int)(e.Height*0.80);
|
||||||
|
int bottomW = widthtotalBottom/3;
|
||||||
|
|
||||||
|
Action<Color,int,IImageProcessingContext> draw=(color,i,ipc)=>{
|
||||||
|
ipc.FillPolygon(color,new PointF(0+(colW*i),0),new PointF(colW + (colW*i),0),new PointF(colW + (colW*i),colH),new PointF(0+(colW*i),colH),new PointF(0+(colW*i),0));
|
||||||
|
};
|
||||||
|
Action<Color,int,IImageProcessingContext> draw_middle = (color,i,ipc)=>{
|
||||||
|
ipc.FillPolygon(color,new PointF(0+(colW*i),colH),new PointF(colW + (colW*i),colH),new PointF(colW + (colW*i),bottomY),new PointF(0+(colW*i),bottomY),new PointF(0+(colW*i),0));
|
||||||
|
|
||||||
|
};
|
||||||
|
Action<Color,int,IImageProcessingContext> draw_bottom = (color,i,ipc)=>{
|
||||||
|
ipc.FillPolygon(color,new PointF(0+(bottomW*i),bottomY),new PointF(bottomW + (bottomW*i),bottomY),new PointF(bottomW + (bottomW*i),e.Height),new PointF(0+(bottomW*i),e.Height),new PointF(0+(bottomW*i),bottomY));
|
||||||
|
};
|
||||||
|
|
||||||
|
e.Mutate((e)=>{
|
||||||
|
var white=Color.White;
|
||||||
|
var yellow = Color.Yellow;
|
||||||
|
var aqua = Color.Aqua;
|
||||||
|
|
||||||
|
var magenta =Color.Magenta;
|
||||||
|
var red=Color.Red;
|
||||||
|
var blue = Color.Blue;
|
||||||
|
var black=Color.Black;
|
||||||
|
var navy=Color.Navy;
|
||||||
|
var lime=Color.Lime;
|
||||||
|
draw(white,0,e);
|
||||||
|
draw(yellow,1,e);
|
||||||
|
draw(aqua,2,e);
|
||||||
|
draw(lime,3,e);
|
||||||
|
draw(magenta,4,e);
|
||||||
|
draw(red,5,e);
|
||||||
|
draw(blue,6,e);
|
||||||
|
draw_middle(red,2,e);
|
||||||
|
draw_middle(blue,1,e);
|
||||||
|
draw_middle(magenta,3,e);
|
||||||
|
draw_middle(lime,4,e);
|
||||||
|
draw_middle(aqua,5,e);
|
||||||
|
draw_middle(yellow,6,e);
|
||||||
|
draw_bottom(navy,0,e);
|
||||||
|
draw_bottom(white,1,e);
|
||||||
|
draw_bottom(navy,2,e);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
return true;
|
||||||
|
},"Test Pattern",0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Library</OutputType>
|
||||||
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="SixLabors.ImageSharp.Drawing" Version="1.0.0-beta14" />
|
||||||
|
|
||||||
|
<PackageReference Include="Tesses.TimelapseApi" Version="1.0.2" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"name": "Test Pattern",
|
||||||
|
"author": "Tesses",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "Draws test pattern when timelapse webcam is not available"
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
#!/bin/bash
|
||||||
|
timelapsepack install
|
||||||
|
cd ~/TimelapseNow/Timelapse.Linux
|
||||||
|
dotnet run
|
Loading…
Reference in New Issue