Sorry that the README is not complete

This commit is contained in:
Mike Nolan 2022-05-20 00:22:28 -05:00
parent 54ccf90b4d
commit c8878722f4
8 changed files with 408 additions and 10 deletions

View File

@ -0,0 +1,17 @@
<Properties>
<MonoDevelop.Ide.Workbench>
<Pads>
<Pad Id="ProjectPad">
<State name="__root__">
<Node name="TimelapseApi" expanded="True" selected="True" />
</State>
</Pad>
</Pads>
</MonoDevelop.Ide.Workbench>
<MonoDevelop.Ide.DebuggingService.PinnedWatches />
<MonoDevelop.Ide.Workspace ActiveConfiguration="Debug" />
<MonoDevelop.Ide.DebuggingService.Breakpoints>
<BreakpointStore />
</MonoDevelop.Ide.DebuggingService.Breakpoints>
<MultiItemStartupConfigurations />
</Properties>

View File

@ -13,6 +13,7 @@ public class GuiData
public async Task Set() public async Task Set()
{ {
if(Instance ==null) return; if(Instance ==null) return;
Api.natfs.api=Instance;
var s= Instance._extSettings; var s= Instance._extSettings;
ExtensionLoader.Data=this; ExtensionLoader.Data=this;
s.Add(( s.Add((
@ -183,12 +184,12 @@ public class Api
public int CurrentFileSystemIndex {get {return Gui.CurrentFSIndex;}} public int CurrentFileSystemIndex {get {return Gui.CurrentFSIndex;}}
internal List<(TimelapseFileSystem FileSystem,string Text,TimelapseExtension Extension)> _fs = CreateFileSystemList(); internal List<(TimelapseFileSystem FileSystem,string Text,TimelapseExtension Extension)> _fs = CreateFileSystemList();
internal static NativeFileSystem natfs=new NativeFileSystem();
internal List<IDisposable> Extensions =new List<IDisposable>(); internal List<IDisposable> Extensions =new List<IDisposable>();
private static List<(TimelapseFileSystem FileSystem,string Text,TimelapseExtension Extension)> CreateFileSystemList() private static List<(TimelapseFileSystem FileSystem,string Text,TimelapseExtension Extension)> CreateFileSystemList()
{ {
List<(TimelapseFileSystem FileSystem,string Text,TimelapseExtension Extension)> fs=new List<(TimelapseFileSystem FileSystem,string Text,TimelapseExtension Extension)>(); List<(TimelapseFileSystem FileSystem,string Text,TimelapseExtension Extension)> fs=new List<(TimelapseFileSystem FileSystem,string Text,TimelapseExtension Extension)>();
fs.Add((new NativeFileSystem(),"Native",TimelapseExtension.Null)); fs.Add((natfs,"Native",TimelapseExtension.Null));
return fs; return fs;
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 B

View File

@ -26,5 +26,8 @@
<PackageReference Include="SixLabors.ImageSharp" Version="2.1.1" /> <PackageReference Include="SixLabors.ImageSharp" Version="2.1.1" />
<PackageReference Include="System.IO.Compression.ZipFile" Version="4.3.0" /> <PackageReference Include="System.IO.Compression.ZipFile" Version="4.3.0" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Assets\*" />
</ItemGroup>
</Project> </Project>

View File

@ -1,6 +1,330 @@
namespace TimelapseApi; namespace TimelapseApi;
using Eto.Forms; using Eto.Forms;
using Eto.Drawing;
using System.Collections.ObjectModel;
using Dir=System.IO.Directory;
using System.Reflection;
internal class OpenDialog : Dialog<string[]>
{
public enum DialogType
{
Open,
Save,
Directory
}
private static Stream[] GetIcons()
{
Stream[] Strms=new Stream[2];
var asm=Assembly.GetExecutingAssembly();
if(asm != null)
{
var strm=asm.GetManifestResourceStream("TimelapseApi.Assets.directory.png");
if(strm != null)
{
Strms[0]=strm;
}
strm=asm.GetManifestResourceStream("TimelapseApi.Assets.file.png");
if(strm != null)
{
Strms[1]=strm;
}
}
return Strms;
}
private Stream[] Icons =GetIcons();
public class OpenFile
{
public OpenFile(Image icon,string name,string path,bool file)
{
Icon=icon;
Name = name;
Path=path;
IsFile=file;
}
public bool IsFile {get;set;}
public string Path {get;set;}
public string Name {get;set;}
public Image Icon {get;set;}
}
Button upBtn=new Button();
TextBox path=new TextBox();
GridView<OpenFile> view=new GridView<OpenFile>();
ObservableCollection<OpenFile> Files=new ObservableCollection<OpenFile>();
Image[] imgs=new Image[2];
public List<FileFilter> Filters {get;set;}
DialogType Type;
DropDown extPick;
public OpenDialog(TimelapseFileSystem fs,DialogType type)
{
Button cancel=new Button {Text="Cancel"};
cancel.Click +=(sender,e)=>{
Result=new string[0];
this.Close();
};
TextBox filename=new TextBox();
filename.PlaceholderText="Filename";
Button createDir = new Button {Text="Create Folder"};
createDir.Click+=(sender,e)=>{
if(string.IsNullOrWhiteSpace(filename.Text))
{
MessageBox.Show("Please type Filename");
}else{
fs.CreateDirectory(TimelapseFileSystem.CombinePath(Directory,filename.Text));
}
};
extPick=new DropDown();
Type=type;
Filters=new List<FileFilter>();
Title=Type == DialogType.Open ? "Open File" : (Type == DialogType.Save ? "Save File" : "Open Directory");
path.KeyDown+=(sender,e)=>{
if(e.Key==Keys.Enter)
{
ListDirectory();
}
};
upBtn.Text="Up";
upBtn.Click+=(sender,e)=>{
string? path=Path.GetDirectoryName(Directory);
if(!string.IsNullOrWhiteSpace(path))
{
Directory=path;
ListDirectory();
}
};
Resizable=true;
Width=640;
Height=480;
imgs[0]=new Bitmap(Icons[0]);
imgs[1]=new Bitmap(Icons[1]);
Directory="/";
Result=new string[0];
FileSystem=fs;
MultiSelect=false;
view.DataStore=Files;
view.Columns.Add(new GridColumn {DataCell =new ImageViewCell("Icon")});
view.Columns.Add(new GridColumn {HeaderText="Name",DataCell=new TextBoxCell("Name"), Editable=false});
view.SelectedItemsChanged+=(sender,e)=>{
List<string> filenames=new List<string>();
foreach(var v in view.SelectedItems)
{
filenames.Add(v.Name);
}
filename.Text=string.Join(',',filenames);
};
view.CellDoubleClick+=(sender,e)=>{
OpenFile f = (OpenFile)e.Item;
if(f.IsFile)
{
if(Type == DialogType.Save)
{
if(MessageBox.Show($"Do you want to overwrite {f.Path}",MessageBoxButtons.YesNo,MessageBoxType.Question,MessageBoxDefaultButton.No) != DialogResult.Yes)
{
return;
}
}
Result=new string[]{f.Path};
this.Close();
}else{
Directory=f.Path;
ListDirectory();
}
};
Button openBtn = new Button {Text=Type == DialogType.Save ? "Save" : "Open"};
openBtn.Click +=(sender,e)=>{
if(Type == DialogType.Directory)
{
if(view.SelectedItems.Any())
{
Result = new string[]{ view.SelectedItem.Path};
this.Close();
return;
}
if(!string.IsNullOrWhiteSpace(filename.Text))
{
if(!FileSystem.DirectoryExists(Directory))
{
return;
}
string dir =TimelapseFileSystem.CombinePath(Directory,filename.Text);
if(FileSystem.DirectoryExists(dir))
{
Result=new string[] {dir};
this.Close();
return;
}
}
if(FileSystem.DirectoryExists(Directory))
{
Result=new string[] {Directory};
this.Close();
return;
}
}
else
{
if(view.SelectedItems.Any())
{
List<string> paths=new List<string>();
foreach(var item in view.SelectedItems)
{
if(!item.IsFile)
{
return;
}
if(Type==DialogType.Save && FileSystem.FileExists(item.Path))
{
if(MessageBox.Show($"Do you want to overwrite {item.Path}",MessageBoxButtons.YesNo,MessageBoxType.Question,MessageBoxDefaultButton.No) != DialogResult.Yes)
{
return;
}
}
paths.Add(item.Path);
}
Result=paths.ToArray();
this.Close();
return;
}
if(!string.IsNullOrWhiteSpace(filename.Text))
{
string dir =TimelapseFileSystem.CombinePath(Directory,filename.Text);
if(!FileSystem.DirectoryExists(Directory))
{
return;
}
if(Type==DialogType.Open)
{
if(FileSystem.FileExists(dir))
{
Result=new string[]{dir};
this.Close();
return;
}
}else{
if(FileSystem.FileExists(dir))
{
if(MessageBox.Show($"Do you want to overwrite {dir}",MessageBoxButtons.YesNo,MessageBoxType.Question,MessageBoxDefaultButton.No) != DialogResult.Yes)
{
return;
}
Result=new string[]{dir};
this.Close();
return;
}else{
Result=new string[]{dir};
this.Close();
return;
}
}
}
}
};
DynamicLayout lyt=new DynamicLayout();
lyt.BeginVertical();
lyt.BeginHorizontal();
lyt.Add(upBtn);
lyt.Add(path,true);
lyt.EndHorizontal();
lyt.EndBeginVertical();
lyt.BeginHorizontal();
lyt.Add(createDir);
lyt.Add(filename,true);
if(Type!=DialogType.Directory)
{
lyt.Add(extPick);
}
lyt.EndHorizontal();
lyt.EndBeginVertical();
lyt.BeginHorizontal();
lyt.AddSpace(true);
lyt.Add(cancel);
lyt.Add(openBtn);
lyt.EndBeginVertical();
lyt.BeginHorizontal();
lyt.Add(view,true,true);
lyt.EndHorizontal();
lyt.EndVertical();
this.Content=lyt;
}
private void ListDirectory()
{
Files.Clear();
foreach(var dir in FileSystem.GetDirectories(Directory))
{
Files.Add(new OpenFile(imgs[0],dir, TimelapseFileSystem.CombinePath(Directory,dir),false));
}
if(Type != DialogType.Directory){
List<string> validExts=new List<string>();
if(Filters.Count > 0 && extPick.SelectedIndex > -1)
{
foreach(var ext in Filters[extPick.SelectedIndex].Extensions)
{
validExts.Add(ext);
}
}
foreach(var dir in FileSystem.GetFiles(Directory))
{
string ext=Path.GetExtension(dir);
bool add=true;
if(validExts.Count > 0)
{
add=validExts.Contains(ext);
}
if(add)
Files.Add(new OpenFile(imgs[1],dir,TimelapseFileSystem.CombinePath(Directory,dir),true));
}
}
}
protected override void OnShown(EventArgs e)
{
foreach(var item in Filters)
{
extPick.Items.Add(item.Name);
}
if(extPick.Items.Count > 0)
{
extPick.SelectedIndex=0;
}
view.AllowMultipleSelection=MultiSelect;
ListDirectory();
extPick.SelectedIndexChanged+=(sender,e)=>{
ListDirectory();
};
}
protected override void OnClosed(EventArgs e)
{
foreach(var i in imgs)
{
if(i!=null && !i.IsDisposed) i.Dispose();
}
foreach(var i in Icons)
{
if(i!=null) i.Dispose();
}
}
public bool MultiSelect {get {return view.AllowMultipleSelection;}set{view.AllowMultipleSelection=value;}}
public string Directory {get {return path.Text;} set{path.Text=value;}}
public TimelapseFileSystem FileSystem {get;set;}
}
public class Protect : TimelapseFileSystem public class Protect : TimelapseFileSystem
{ {
TimelapseFileSystem fs; TimelapseFileSystem fs;
@ -68,6 +392,7 @@ public class Protect : TimelapseFileSystem
} }
public class NativeFileSystem : TimelapseFileSystem public class NativeFileSystem : TimelapseFileSystem
{ {
internal Api? api;
public override void CreateDirectory(string path) public override void CreateDirectory(string path)
{ {
Directory.CreateDirectory(path); Directory.CreateDirectory(path);
@ -105,6 +430,9 @@ public class NativeFileSystem : TimelapseFileSystem
} }
public override string? ShowDirectoryDialog(Window parent, string startDir = "") public override string? ShowDirectoryDialog(Window parent, string startDir = "")
{ {
if(api != null && api.Model.useCustomFilePickerForNativeFS) {
return base.ShowDirectoryDialog(parent,startDir);
}
using(var d = new SelectFolderDialog()) using(var d = new SelectFolderDialog())
{ {
if(!string.IsNullOrWhiteSpace(startDir)) if(!string.IsNullOrWhiteSpace(startDir))
@ -116,6 +444,9 @@ public class NativeFileSystem : TimelapseFileSystem
} }
public override string[] ShowOpenDialog(Window parent, FileFilter[] filters,bool multi, string startDir = "") public override string[] ShowOpenDialog(Window parent, FileFilter[] filters,bool multi, string startDir = "")
{ {
if(api != null && api.Model.useCustomFilePickerForNativeFS) {
return base.ShowOpenDialog(parent,filters,multi,startDir);
}
using(var ofd=new OpenFileDialog()) using(var ofd=new OpenFileDialog())
{ {
ofd.MultiSelect = multi; ofd.MultiSelect = multi;
@ -132,6 +463,9 @@ public class NativeFileSystem : TimelapseFileSystem
} }
public override string? ShowSaveDialog(Window parent, FileFilter[] filters, string startDir = "") public override string? ShowSaveDialog(Window parent, FileFilter[] filters, string startDir = "")
{ {
if(api != null && api.Model.useCustomFilePickerForNativeFS) {
return base.ShowSaveDialog(parent,filters,startDir);
}
using(var sfd=new SaveFileDialog()) using(var sfd=new SaveFileDialog())
{ {
if(!string.IsNullOrWhiteSpace(startDir)) if(!string.IsNullOrWhiteSpace(startDir))
@ -186,16 +520,52 @@ public abstract class TimelapseFileSystem
} }
public virtual string[] ShowOpenDialog(Window parent,FileFilter[] filters,bool multi,string startDir="") public virtual string[] ShowOpenDialog(Window parent,FileFilter[] filters,bool multi,string startDir="")
{ {
throw new Exception(); using(var ofd=new OpenDialog(this,OpenDialog.DialogType.Open))
{
ofd.MultiSelect=multi;
foreach(var f in filters)
{
ofd.Filters.Add(f);
}
if(!string.IsNullOrWhiteSpace(startDir))
{
ofd.Directory=startDir;
}
return ofd.ShowModal(parent);
}
} }
public virtual string? ShowSaveDialog(Window parent,FileFilter[] filters,string startDir="") public virtual string? ShowSaveDialog(Window parent,FileFilter[] filters,string startDir="")
{ {
throw new Exception(); using(var ofd=new OpenDialog(this,OpenDialog.DialogType.Save))
{
foreach(var f in filters)
{
ofd.Filters.Add(f);
}
if(!string.IsNullOrWhiteSpace(startDir))
{
ofd.Directory=startDir;
}
var res=ofd.ShowModal(parent);
return res.Length == 1 ? res[0] : null;
}
} }
public virtual string? ShowDirectoryDialog(Window parent,string startDir="") public virtual string? ShowDirectoryDialog(Window parent,string startDir="")
{ {
throw new Exception(); using(var ofd=new OpenDialog(this,OpenDialog.DialogType.Directory))
{
if(!string.IsNullOrWhiteSpace(startDir))
{
ofd.Directory=startDir;
}
var res=ofd.ShowModal(parent);
return res.Length == 1 ? res[0] : null;
}
} }
public int GetNumberOfFiles(string path,string filter="*") public int GetNumberOfFiles(string path,string filter="*")
@ -256,7 +626,7 @@ public abstract class TimelapseFileSystem
public abstract bool DirectoryExists(string path); public abstract bool DirectoryExists(string path);
public static string CombinePath(string p1,string p2) public static string CombinePath(string p1,string p2)
{ {
return Path.Combine(p1,p2).Replace(Path.DirectorySeparatorChar,'/'); return Path.Combine(p1,p2.TrimStart('/')).Replace(Path.DirectorySeparatorChar,'/');
} }
public abstract Stream Open(string path,FileMode mode,FileAccess access,FileShare share); public abstract Stream Open(string path,FileMode mode,FileAccess access,FileShare share);

View File

@ -133,9 +133,11 @@ internal class TimelapseSettings : Dialog
Button installExtension = new Button{ Button installExtension = new Button{
Text="Install Extension" Text="Install Extension"
}; };
CheckBox enableExt=new CheckBox(); CheckBox enableExt=new CheckBox{Text="Add extensions on install"};
enableExt.Text="Add extensions on install";
enableExt.Checked = api.Model.addExtensionOnInstall; enableExt.Checked = api.Model.addExtensionOnInstall;
CheckBox useCustomFilePickerForNativeFS = new CheckBox{Text="Use Custom File Picker For Native FileSystem"};
useCustomFilePickerForNativeFS.Checked=api.Model.useCustomFilePickerForNativeFS;
installExtension.Click += async(sender,e)=>{ installExtension.Click += async(sender,e)=>{
using(var ofd=new OpenFileDialog()) using(var ofd=new OpenFileDialog())
{ {
@ -205,6 +207,8 @@ internal class TimelapseSettings : Dialog
lyt2.AddRow(lyt); lyt2.AddRow(lyt);
lyt2.AddRow(installExtension); lyt2.AddRow(installExtension);
lyt2.AddRow(enableExt); lyt2.AddRow(enableExt);
lyt2.AddRow(useCustomFilePickerForNativeFS);
lyt2.AddRow(null); lyt2.AddRow(null);
lyt2.EndVertical(); lyt2.EndVertical();
@ -222,6 +226,7 @@ internal class TimelapseSettings : Dialog
api.Model.enableWebServer=enableServer.Checked.GetValueOrDefault(); api.Model.enableWebServer=enableServer.Checked.GetValueOrDefault();
api.Model.timelapsePort=(ushort)stepper.Value; api.Model.timelapsePort=(ushort)stepper.Value;
api.Model.addExtensionOnInstall = enableExt.Checked.GetValueOrDefault(); api.Model.addExtensionOnInstall = enableExt.Checked.GetValueOrDefault();
api.Model.useCustomFilePickerForNativeFS = useCustomFilePickerForNativeFS.Checked.GetValueOrDefault();
foreach(var item in coll.Items) foreach(var item in coll.Items)
{ {
if(!item.OverlayChecked) if(!item.OverlayChecked)
@ -235,6 +240,7 @@ internal class TimelapseSettings : Dialog
} }
api.SaveModel(); api.SaveModel();
this.Close();
}; };
lyt1.EndBeginHorizontal(); lyt1.EndBeginHorizontal();

View File

@ -13,6 +13,7 @@ public class TimelapseSettingsModel
addExtensionOnInstall=true; addExtensionOnInstall=true;
} }
public bool useCustomFilePickerForNativeFS {get;set;}
public bool addExtensionOnInstall {get;set;} public bool addExtensionOnInstall {get;set;}
public bool canOverlayVideo {get;set;} public bool canOverlayVideo {get;set;}
public bool canBlockFrames {get;set;} public bool canBlockFrames {get;set;}