1392 lines
43 KiB
C#
1392 lines
43 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel;
|
|
using System.Drawing;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using System.Windows.Forms;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using RokettoLaunch.Models.SaveFile;
|
|
using RokettoLaunch.Windows.Forms;
|
|
using RyzStudio;
|
|
using RyzStudio.Windows.Forms;
|
|
using RyzStudio.Windows.ThemedForms;
|
|
using RyzStudio.Windows.ThemedForms.ButtonTextBox;
|
|
using RyzStudio.Windows.TileForms;
|
|
|
|
namespace RokettoLaunch
|
|
{
|
|
public partial class MainForm : Form
|
|
{
|
|
//private const int MIN_COLUMNS = 4;
|
|
//private const int TILE_SIZE = 70;
|
|
//private const int TILE_PADDING = 3;
|
|
|
|
private readonly IServiceProvider _provider;
|
|
private readonly IFileSessionManager _fileSessionManager;
|
|
|
|
private bool _isBusy = false;
|
|
private bool _requestExit = false;
|
|
|
|
|
|
public MainForm()
|
|
{
|
|
InitializeComponent();
|
|
|
|
this.AutoScaleMode = AutoScaleMode.None;
|
|
this.Text = Application.ProductName;
|
|
|
|
this.CurrentSession = new App4Options();
|
|
|
|
//#if DEBUG
|
|
//flowLayoutPanel1.BackColor = Color.LightGreen;
|
|
//#endif
|
|
|
|
notifyIcon1.Text = Application.ProductName;
|
|
}
|
|
|
|
public MainForm(IServiceProvider provider, IFileSessionManager fileSessionManager) : this()
|
|
{
|
|
_provider = provider;
|
|
_fileSessionManager = fileSessionManager;
|
|
|
|
_fileSessionManager.OpenFileDialog = openFileDialog1;
|
|
_fileSessionManager.SaveFileDialog = saveFileDialog1;
|
|
_fileSessionManager.OnNewing += fileSessionManager_OnNewSession;
|
|
_fileSessionManager.OnLoading += fileSessionManager_OnLoadSession;
|
|
_fileSessionManager.OnSaving += fileSessionManager_OnSaveSession;
|
|
_fileSessionManager.OnClearing += fileSessionManager_OnClearSession;
|
|
_fileSessionManager.OnFilenameChanged += fileSessionManager_OnFilenameChanged;
|
|
}
|
|
|
|
protected async override void OnShown(EventArgs e)
|
|
{
|
|
base.OnShown(e);
|
|
|
|
var args = WinApplication.GetCommandLine();
|
|
|
|
string jsonfigFilename = args.Where(x => (x.Key.Equals("o") || x.Key.Equals("open"))).Select(x => x.Value).FirstOrDefault();
|
|
if (string.IsNullOrWhiteSpace(jsonfigFilename))
|
|
{
|
|
jsonfigFilename = Path.ChangeExtension(Application.ExecutablePath, "jsonfig");
|
|
}
|
|
|
|
jsonfigFilename = @"L:\gitea-hiimray\2025-11-18-1429 - Copy.jsnx";
|
|
|
|
if (!string.IsNullOrWhiteSpace(jsonfigFilename) && File.Exists(jsonfigFilename))
|
|
{
|
|
await _fileSessionManager.OpenSession(jsonfigFilename);
|
|
}
|
|
else
|
|
{
|
|
await _fileSessionManager.NewSession();
|
|
}
|
|
|
|
UIControl.SetFocus(this);
|
|
}
|
|
|
|
protected async override void OnFormClosing(FormClosingEventArgs e)
|
|
{
|
|
base.OnFormClosing(e);
|
|
|
|
if (this.CurrentSession == null)
|
|
{
|
|
this.CurrentSession = new App4Options();
|
|
}
|
|
|
|
if (this.CurrentSession.HideOnClose && !_requestExit)
|
|
{
|
|
e.Cancel = true;
|
|
return;
|
|
}
|
|
|
|
_requestExit = false;
|
|
|
|
var result = await _fileSessionManager.CloseSession();
|
|
if (!result)
|
|
{
|
|
e.Cancel = true;
|
|
return;
|
|
}
|
|
|
|
if ((this.CurrentSession?.ShowToggleHotkey ?? new ThKeyCodeTextBox.Results()).Key != Keys.None)
|
|
{
|
|
#if !DEBUG
|
|
RyzStudio.Runtime.InteropServices.User32.UnregisterHotKey((IntPtr)Handle, 1);
|
|
#endif
|
|
}
|
|
}
|
|
|
|
protected override void WndProc(ref Message m)
|
|
{
|
|
switch (m.Msg)
|
|
{
|
|
case RyzStudio.Runtime.InteropServices.User32.WM_HOTKEY:
|
|
if (m.WParam.ToInt32() == 1)
|
|
{
|
|
this.Visible = !this.Visible;
|
|
}
|
|
|
|
break;
|
|
case RyzStudio.Runtime.InteropServices.User32.WM_QUERYENDSESSION:
|
|
_requestExit = true;
|
|
|
|
Application.Exit();
|
|
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
base.WndProc(ref m);
|
|
}
|
|
|
|
|
|
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
|
public App4Options CurrentSession { get; set; } = null;
|
|
|
|
|
|
private void InvalidateOptions(bool resize)
|
|
{
|
|
if (resize)
|
|
{
|
|
if (!this.CurrentSession.StartPosition.IsEmpty)
|
|
{
|
|
UIControl.SetLocation(this, this.CurrentSession.StartPosition);
|
|
}
|
|
|
|
if (this.CurrentSession.Width > 0)
|
|
{
|
|
UIControl.SetClientWidth(this, this.CurrentSession.Width);
|
|
}
|
|
|
|
if (this.CurrentSession.Height > 0)
|
|
{
|
|
UIControl.SetClientHeight(this, this.CurrentSession.Height);
|
|
}
|
|
}
|
|
|
|
/// todo: big icons
|
|
|
|
#if !DEBUG
|
|
UIControl.Invoke(this, (x) =>
|
|
{
|
|
RyzStudio.Runtime.InteropServices.User32.UnregisterHotKey((IntPtr)Handle, 1);
|
|
});
|
|
|
|
if ((this.CurrentSession?.ShowToggleHotkey ?? new ThKeyCodeTextBox.Results()).Key != Keys.None)
|
|
{
|
|
UIControl.Invoke(this, (x) =>
|
|
{
|
|
RyzStudio.Runtime.InteropServices.User32.RegisterHotKey((IntPtr)Handle, 1, this.CurrentSession.ShowToggleHotkey.ModifierCode, this.CurrentSession.ShowToggleHotkey.KeyCode);
|
|
});
|
|
}
|
|
#endif
|
|
|
|
UIControl.SetTopMost(this, this.CurrentSession.AlwaysOnTop);
|
|
}
|
|
|
|
private void MainMenuStrip_MenuActivate(object sender, EventArgs e)
|
|
{
|
|
closeToolStripMenuItem.Enabled = (_fileSessionManager.SessionState != FileSessionManager.SessionStateEnum.Close);
|
|
|
|
saveToolStripMenuItem.Enabled = (_fileSessionManager.SessionState == FileSessionManager.SessionStateEnum.Open) && _fileSessionManager.HasChanged;
|
|
saveAsToolStripMenuItem.Enabled = (_fileSessionManager.SessionState != FileSessionManager.SessionStateEnum.Close);
|
|
|
|
addGroupToolStripMenuItem.Enabled = (_fileSessionManager.SessionState != FileSessionManager.SessionStateEnum.Close);
|
|
|
|
showBigIconsToolStripMenuItem.Checked = this.CurrentSession?.ShowBigIcons ?? true;
|
|
alwaysOnTopToolStripMenuItem.Checked = this.CurrentSession?.AlwaysOnTop ?? false;
|
|
}
|
|
|
|
|
|
#region Main Menu
|
|
|
|
/// <summary>
|
|
/// New
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
private async void NewToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
if (_isBusy)
|
|
{
|
|
return;
|
|
}
|
|
|
|
await _fileSessionManager.NewSession();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Open
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
private async void OpenToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
if (_isBusy)
|
|
{
|
|
return;
|
|
}
|
|
|
|
await _fileSessionManager.OpenSession();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Close
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
private async void CloseToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
if (_isBusy)
|
|
{
|
|
return;
|
|
}
|
|
|
|
await _fileSessionManager.CloseSession();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Save
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
private async void SaveToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
if (_isBusy)
|
|
{
|
|
return;
|
|
}
|
|
|
|
await _fileSessionManager.SaveSession();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Save As
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
private async void SaveAsToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
if (_isBusy)
|
|
{
|
|
return;
|
|
}
|
|
|
|
await _fileSessionManager.SaveAsSession();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Exit
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
private void ExitToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
if (_isBusy)
|
|
{
|
|
return;
|
|
}
|
|
|
|
_requestExit = true;
|
|
|
|
this.Close();
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Add group
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
private async void AddGroupToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
var group = new App4Options.Group()
|
|
{
|
|
Id = Guid.NewGuid(),
|
|
Title = "New Group",
|
|
IsOpen = true,
|
|
GridSize = new Size(this.CurrentSession.TilesPerRow, 1)
|
|
};
|
|
|
|
this.CurrentSession.Groups.Add(group);
|
|
this.AddGroup(group);
|
|
|
|
_fileSessionManager.HasChanged = true;
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Show big icons
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
private void ShowBigIconsToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
if (this.CurrentSession == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
this.CurrentSession.ShowBigIcons = !this.CurrentSession.ShowBigIcons;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Always on top
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
private void AlwaysOnTopToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
if (this.CurrentSession == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
this.CurrentSession.AlwaysOnTop = !this.CurrentSession.AlwaysOnTop;
|
|
|
|
this.TopMost = this.CurrentSession.AlwaysOnTop;
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Options
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
private void OptionsToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
var form = new OptionsForm(this.CurrentSession);
|
|
if (form.ShowDialog() == DialogResult.OK)
|
|
{
|
|
this.CurrentSession = form.Result;
|
|
|
|
InvalidateOptions(false);
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// View help
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
private void ViewHelpToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
RyzStudio.Diagnostics.Process.Execute(AppResource.AppHelpURL);
|
|
}
|
|
|
|
/// <summary>
|
|
/// About
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
private void AboutToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
var form = new RyzStudio.Windows.ThemedForms.AboutForm();
|
|
form.ProductURL = AppResource.AppProductURL;
|
|
form.AuthorURL = AppResource.AppAuthorURL;
|
|
form.CompanyURL = AppResource.AppCompanyURL;
|
|
form.ProductCopyrightStartYear = 2020;
|
|
form.ProductLogo = AppResource.icon_64;
|
|
|
|
form.ShowDialog();
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Notification Icon
|
|
|
|
private void NotifyIcon_MouseClick(object sender, MouseEventArgs e)
|
|
{
|
|
if (e.Button == MouseButtons.Left)
|
|
{
|
|
this.Visible = !this.Visible;
|
|
}
|
|
}
|
|
|
|
private void NotifyExitToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
if (_isBusy)
|
|
{
|
|
return;
|
|
}
|
|
|
|
_requestExit = true;
|
|
|
|
this.Close();
|
|
}
|
|
|
|
#endregion
|
|
|
|
|
|
#region File Session Manager
|
|
|
|
private async Task<bool> fileSessionManager_OnNewSession(FileSessionManager sender)
|
|
{
|
|
// Enforce minimum number of rows
|
|
this.CurrentSession.TilesPerRow = Math.Max(this.CurrentSession.TilesPerRow, TileLayoutPanel.MIN_COLUMNS);
|
|
|
|
UIControl.Clear(flowLayoutPanel1);
|
|
|
|
AddGroupToolStripMenuItem_Click(null, null);
|
|
|
|
InvalidateOptions(false);
|
|
|
|
return true;
|
|
}
|
|
|
|
private async Task<bool> fileSessionManager_OnLoadSession(FileSessionManager sender, string filename, int formatType)
|
|
{
|
|
// Progress indicator
|
|
var loadingForm = _provider.GetRequiredService<LoadingForm>();
|
|
var result = await loadingForm.ShowDialog(filename);
|
|
if (result != DialogResult.OK)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
await Task.Run(() =>
|
|
{
|
|
this.CurrentSession = loadingForm.Result;
|
|
|
|
InvalidateOptions(true);
|
|
|
|
foreach (var group in this.CurrentSession.Groups ?? new List<App4Options.Group>())
|
|
{
|
|
var gridSize = group.GetMaxGridSize();
|
|
gridSize.Width = Math.Max(gridSize.Width, TileLayoutPanel.MIN_COLUMNS);
|
|
|
|
group.GridSize = new Size(gridSize.Width, gridSize.Height);
|
|
|
|
this.AddGroup(group);
|
|
}
|
|
|
|
});
|
|
|
|
return true;
|
|
}
|
|
|
|
private async Task<bool> fileSessionManager_OnSaveSession(FileSessionManager sender, string filename, int formatType, bool showNotices)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(filename))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return await Task.Run(async () =>
|
|
{
|
|
if (_isBusy)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
_isBusy = true;
|
|
|
|
// update session
|
|
if (this.CurrentSession == null)
|
|
{
|
|
this.CurrentSession = new App4Options();
|
|
}
|
|
|
|
this.CurrentSession.StartPosition = this.Location;
|
|
this.CurrentSession.Width = this.DisplayRectangle.Width;
|
|
this.CurrentSession.Height = this.DisplayRectangle.Height;
|
|
|
|
var result = GenericResult.Create();
|
|
|
|
switch (Path.GetExtension(filename?.ToLower()?.Trim() ?? string.Empty))
|
|
{
|
|
case ".json":
|
|
case ".jsonfig":
|
|
result = RyzStudio.Text.Json.JsonSerialiser.SerialiseFile(filename, this.CurrentSession);
|
|
break;
|
|
case ".jsnx":
|
|
try
|
|
{
|
|
System.IO.File.Delete(filename);
|
|
}
|
|
catch (Exception)
|
|
{
|
|
// do nothing
|
|
}
|
|
|
|
result = await RyzStudio.IO.Compression.ZFile.WriteFile(filename, "Document.json", this.CurrentSession);
|
|
break;
|
|
default:
|
|
result = GenericResult.Fault("Format not supported");
|
|
break;
|
|
}
|
|
|
|
if (result.IsSuccess)
|
|
{
|
|
if (showNotices)
|
|
{
|
|
ThMessageBox.Show(this, "Session saved!", "Save session", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (showNotices)
|
|
{
|
|
ThMessageBox.Show(this, "Session saved!", "Save session");
|
|
}
|
|
}
|
|
|
|
_isBusy = false;
|
|
|
|
return result.IsSuccess;
|
|
});
|
|
}
|
|
|
|
private async Task<bool> fileSessionManager_OnClearSession(FileSessionManager sender)
|
|
{
|
|
UIControl.Clear(flowLayoutPanel1);
|
|
|
|
return true;
|
|
}
|
|
|
|
private async Task fileSessionManager_OnFilenameChanged(FileSessionManager sender, string filename)
|
|
{
|
|
await Task.Run(() =>
|
|
{
|
|
switch (sender.SessionState)
|
|
{
|
|
case FileSessionManager.SessionStateEnum.New:
|
|
UIControl.SetText(this, "New Session - " + Application.ProductName);
|
|
break;
|
|
case FileSessionManager.SessionStateEnum.Open:
|
|
UIControl.SetText(this, Path.GetFileNameWithoutExtension(filename) + " - " + Application.ProductName);
|
|
break;
|
|
case FileSessionManager.SessionStateEnum.Close:
|
|
UIControl.SetText(this, Application.ProductName);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
});
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Group
|
|
|
|
/// <summary>
|
|
/// Add Tile
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
private void AddTileToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
var panel = UIControl.GetOwner<TToggleHeaderPanel>((ToolStripMenuItem)sender);
|
|
if (panel == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (panel.ToggleControlId == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var groupInfo = this.CurrentSession.Groups.Where(x => x.Id == panel.ToggleControlId.Value).FirstOrDefault();
|
|
if (groupInfo == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var newTileInfo = new App4Options.Item()
|
|
{
|
|
Id = Guid.NewGuid(),
|
|
Title = "New Tile",
|
|
IsGroup = false,
|
|
Position = new Point(-1, -1)
|
|
};
|
|
|
|
newTileInfo = groupInfo.AddItem(newTileInfo);
|
|
|
|
// Update table layout
|
|
var newTilePanel = CreateTile(newTileInfo);
|
|
|
|
var tableLayout = (TileLayoutPanel)panel.ToggleControl;
|
|
tableLayout.AddTilePanel(newTilePanel, newTileInfo.Position.X, newTileInfo.Position.Y);
|
|
tableLayout.SetGridSize(groupInfo.GridSize);
|
|
|
|
_fileSessionManager.HasChanged = true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add Folder
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
private void AddFolderToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
var panel = UIControl.GetOwner<TToggleHeaderPanel>((ToolStripMenuItem)sender);
|
|
if (panel == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (panel.ToggleControlId == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var groupInfo = this.CurrentSession.Groups.Where(x => x.Id == panel.ToggleControlId.Value).FirstOrDefault();
|
|
if (groupInfo == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var newTileInfo = new App4Options.Item()
|
|
{
|
|
Id = Guid.NewGuid(),
|
|
Title = "New Folder",
|
|
IsGroup = true,
|
|
Position = new Point(-1, -1)
|
|
};
|
|
|
|
newTileInfo = groupInfo.AddItem(newTileInfo);
|
|
|
|
// Update table layout
|
|
var newTilePanel = CreateTile(newTileInfo);
|
|
|
|
var tableLayout = (TileLayoutPanel)panel.ToggleControl;
|
|
tableLayout.AddTilePanel(newTilePanel, newTileInfo.Position.X, newTileInfo.Position.Y);
|
|
tableLayout.SetGridSize(groupInfo.GridSize);
|
|
|
|
_fileSessionManager.HasChanged = true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Edit
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
private void EditGroupToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
var panel = UIControl.GetOwner<TToggleHeaderPanel>((ToolStripMenuItem)sender);
|
|
if (panel == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (panel.ToggleControlId == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var groupInfo = this.CurrentSession.Groups.Where(x => x.Id == panel.ToggleControlId.Value).FirstOrDefault();
|
|
if (groupInfo == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var editGroupForm = new EditGroupForm(groupInfo);
|
|
if (editGroupForm.ShowDialog() == DialogResult.OK)
|
|
{
|
|
var newGroupInfo = editGroupForm.Result;
|
|
|
|
groupInfo.Title = newGroupInfo.Title;
|
|
groupInfo.IsOpen = newGroupInfo.IsOpen;
|
|
|
|
panel.Title = newGroupInfo.Title;
|
|
panel.Invalidate();
|
|
|
|
_fileSessionManager.HasChanged = true;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Duplicate
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
private async void toolStripMenuItem5_Click(object sender, EventArgs e)
|
|
{
|
|
var panel = UIControl.GetOwner<TToggleHeaderPanel>((ToolStripMenuItem)sender);
|
|
if (panel == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (panel.ToggleControlId == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var groupInfo = this.CurrentSession.Groups.Where(x => x.Id == panel.ToggleControlId.Value).FirstOrDefault();
|
|
if (groupInfo == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
_isBusy = true;
|
|
|
|
await Task.Run(() =>
|
|
{
|
|
var newGroupInfo = groupInfo.CopyOf();
|
|
|
|
this.CurrentSession.Groups.Add(newGroupInfo);
|
|
this.AddGroup(newGroupInfo);
|
|
});
|
|
|
|
_fileSessionManager.HasChanged = true;
|
|
_isBusy = false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Move Top
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
private void MoveTopToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
var panel = UIControl.GetOwner<TToggleHeaderPanel>((ToolStripDropDownItem)sender);
|
|
if (panel == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Move header
|
|
UIControl.MoveTop(flowLayoutPanel1, panel);
|
|
|
|
// Move sidecar
|
|
if (panel.ToggleControl != null)
|
|
{
|
|
UIControl.MoveNext(flowLayoutPanel1, panel, panel.ToggleControl);
|
|
}
|
|
|
|
// Move group
|
|
var n = this.CurrentSession.Groups.FindIndex(x => x.Id == panel.ToggleControlId);
|
|
if (n >= 0)
|
|
{
|
|
var item = this.CurrentSession.Groups[n];
|
|
|
|
this.CurrentSession.Groups.RemoveAt(n);
|
|
this.CurrentSession.Groups.Insert(0, item);
|
|
}
|
|
|
|
_fileSessionManager.HasChanged = true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Move Up
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
private void MoveUpToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
var panel = UIControl.GetOwner<TToggleHeaderPanel>((ToolStripDropDownItem)sender);
|
|
if (panel == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Move header
|
|
UIControl.MovePos(flowLayoutPanel1, panel, -2);
|
|
|
|
// Move sidecar
|
|
if (panel.ToggleControl != null)
|
|
{
|
|
UIControl.MoveNext(flowLayoutPanel1, panel, panel.ToggleControl);
|
|
}
|
|
|
|
// Move group
|
|
var n = this.CurrentSession.Groups.FindIndex(x => x.Id == panel.ToggleControlId);
|
|
if (n > 0)
|
|
{
|
|
var item = this.CurrentSession.Groups[n];
|
|
|
|
this.CurrentSession.Groups.RemoveAt(n);
|
|
this.CurrentSession.Groups.Insert((n - 1), item);
|
|
}
|
|
|
|
_fileSessionManager.HasChanged = true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Move Down
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
private void MoveDownToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
var panel = UIControl.GetOwner<TToggleHeaderPanel>((ToolStripDropDownItem)sender);
|
|
if (panel == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Move header
|
|
UIControl.MovePos(flowLayoutPanel1, panel, 3);
|
|
|
|
// Move sidecar
|
|
if (panel.ToggleControl != null)
|
|
{
|
|
UIControl.MovePos(flowLayoutPanel1, panel.ToggleControl, 3);
|
|
}
|
|
|
|
// Move group
|
|
var n = this.CurrentSession.Groups.FindIndex(x => x.Id == panel.ToggleControlId);
|
|
if ((n >= 0) && (n < (this.CurrentSession.Groups.Count - 1)))
|
|
{
|
|
var item = this.CurrentSession.Groups[n];
|
|
|
|
this.CurrentSession.Groups.RemoveAt(n);
|
|
this.CurrentSession.Groups.Insert((n + 1), item);
|
|
}
|
|
|
|
_fileSessionManager.HasChanged = true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Move Bottom
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
private void MoveBottomToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
var panel = UIControl.GetOwner<TToggleHeaderPanel>((ToolStripDropDownItem)sender);
|
|
if (panel == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Move header
|
|
UIControl.MoveBottom(flowLayoutPanel1, panel);
|
|
|
|
// Move sidecar
|
|
if (panel.ToggleControl != null)
|
|
{
|
|
UIControl.MoveNext(flowLayoutPanel1, panel, panel.ToggleControl);
|
|
}
|
|
|
|
// Move group
|
|
var lastPos = (this.CurrentSession.Groups.Count - 1);
|
|
var n = this.CurrentSession.Groups.FindIndex(x => x.Id == panel.ToggleControlId);
|
|
if ((n >= 0) && (n < lastPos))
|
|
{
|
|
var item = this.CurrentSession.Groups[n];
|
|
|
|
this.CurrentSession.Groups.RemoveAt(n);
|
|
this.CurrentSession.Groups.Insert(lastPos, item);
|
|
}
|
|
|
|
_fileSessionManager.HasChanged = true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
private void RemoveGroupToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
var result = MessageBox.Show("Are you sure you want to remove section?", "Remove Section", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);
|
|
if (result != DialogResult.Yes)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var panel = UIControl.GetOwner<TToggleHeaderPanel>((ToolStripMenuItem)sender);
|
|
if (panel?.Parent == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Remove side-car
|
|
if (panel.ToggleControl != null)
|
|
{
|
|
if (panel.ToggleControl.Parent != null)
|
|
{
|
|
if (panel.ToggleControlId.HasValue)
|
|
{
|
|
this.CurrentSession.Remove(panel.ToggleControlId.Value);
|
|
}
|
|
|
|
panel.ToggleControl.Parent.Controls.Remove(panel.ToggleControl);
|
|
}
|
|
}
|
|
|
|
// Remove header
|
|
panel?.Parent.Controls?.Remove(panel);
|
|
|
|
_fileSessionManager.HasChanged = true;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Tile
|
|
|
|
/// <summary>
|
|
/// Edit
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
private void EditTileToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
var tilePanel = UIControl.GetOwner<TilePanel>((ToolStripMenuItem)sender);
|
|
|
|
var tileInfo = this.GetTileInfo(tilePanel);
|
|
if (tileInfo == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
App4Options.Item resultTileInfo = null;
|
|
|
|
if (tileInfo.IsGroup)
|
|
{
|
|
var editFolderForm = new EditFolderForm(tileInfo);
|
|
if (editFolderForm.ShowDialog() == DialogResult.OK)
|
|
{
|
|
resultTileInfo = editFolderForm.Result;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
var editForm = new EditTileForm(tileInfo);
|
|
if (editForm.ShowDialog() == DialogResult.OK)
|
|
{
|
|
resultTileInfo = editForm.Result;
|
|
}
|
|
}
|
|
|
|
if (resultTileInfo == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var updatedTileInfo = this.CurrentSession.FindById(tileInfo.Id);
|
|
updatedTileInfo.Load(resultTileInfo);
|
|
|
|
this.UpdateTile(tilePanel, updatedTileInfo);
|
|
|
|
_fileSessionManager.HasChanged = true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Copy To
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
private async void CopyToTileToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
var tilePanel = UIControl.GetOwner<TilePanel>((ToolStripMenuItem)sender);
|
|
|
|
var tileInfo = this.GetTileInfo(tilePanel);
|
|
if (tileInfo == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var groups = this.CurrentSession.Groups.Select(x => x.Title)?.ToList() ?? new List<string>();
|
|
|
|
var copyToTileForm = new CopyToTileForm(groups);
|
|
if (copyToTileForm.ShowDialog() == DialogResult.OK)
|
|
{
|
|
var n = copyToTileForm.Result;
|
|
|
|
await Task.Run(() =>
|
|
{
|
|
var newTileInfo = tileInfo.CopyOf();
|
|
|
|
var headers = flowLayoutPanel1.Controls.OfType<TToggleHeaderPanel>().ToList();
|
|
if (headers != null)
|
|
{
|
|
if (n >= 0 && n <= (headers.Count - 1))
|
|
{
|
|
// Add to group
|
|
newTileInfo = this.CurrentSession.Groups[n].AddItem(newTileInfo);
|
|
|
|
// Update table layout
|
|
var newTilePanel = CreateTile(newTileInfo);
|
|
|
|
var tableLayout = (TileLayoutPanel)headers[n].ToggleControl;
|
|
tableLayout.AddTilePanel(newTilePanel, newTileInfo.Position.X, newTileInfo.Position.Y);
|
|
tableLayout.SetGridSize(this.CurrentSession.Groups[n].GridSize);
|
|
|
|
|
|
}
|
|
}
|
|
|
|
});
|
|
|
|
_fileSessionManager.HasChanged = true;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
private void RemoveTileToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
var tilePanel = UIControl.GetOwner<TilePanel>((ToolStripMenuItem)sender);
|
|
|
|
var tileInfo = this.GetTileInfo(tilePanel);
|
|
if (tileInfo == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var dialogResult = MessageBox.Show(this, "Are you sure you want to remove tile?", "Remove Tile", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);
|
|
if (dialogResult != DialogResult.Yes)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var result = this.CurrentSession.Remove(tileInfo.Id);
|
|
if (result)
|
|
{
|
|
tilePanel.Parent.Controls.Remove(tilePanel);
|
|
|
|
_fileSessionManager.HasChanged = true;
|
|
}
|
|
else
|
|
{
|
|
MessageBox.Show(this, "Unable to remove tile", "Remove Tile", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
|
|
private void AddGroup(App4Options.Group groupInfo)
|
|
{
|
|
var tableLayout = CreateTable(groupInfo.GridSize);
|
|
tableLayout.GroupId = groupInfo.Id;
|
|
|
|
var header = CreateHeader(groupInfo);
|
|
header.ToggleControlId = groupInfo.Id;
|
|
header.ToggleControl = tableLayout;
|
|
|
|
UIControl.Add(flowLayoutPanel1, header);
|
|
UIControl.Add(flowLayoutPanel1, tableLayout);
|
|
|
|
foreach (var item in groupInfo.Items ?? new List<App4Options.Item>())
|
|
{
|
|
var tilePanel = CreateTile(item);
|
|
|
|
tableLayout.AddTilePanel(tilePanel, item.Position.X, item.Position.Y);
|
|
}
|
|
|
|
tableLayout.SetGridSize(groupInfo.GridSize);
|
|
}
|
|
|
|
private void AddToFolder(App4Options.Item item, List<string> paths, bool appendTo = true)
|
|
{
|
|
item.IsGroup = true;
|
|
|
|
if (!appendTo)
|
|
{
|
|
item.Items.Clear();
|
|
}
|
|
|
|
foreach (var path in paths)
|
|
{
|
|
var newTileInfo = new App4Options.Item()
|
|
{
|
|
Id = Guid.NewGuid(),
|
|
IsGroup = false,
|
|
TargetPath = path,
|
|
};
|
|
|
|
newTileInfo.ResolvePaths();
|
|
newTileInfo.Title = RyzStudio.IO.File.GetName(newTileInfo.ResolvedTargetPath);
|
|
|
|
item.Items.Add(newTileInfo);
|
|
}
|
|
}
|
|
|
|
private TileLayoutPanel CreateTable(Size gridSize)
|
|
{
|
|
var layoutPanel = new TileLayoutPanel();
|
|
layoutPanel.DragDrop += LayoutPanel_DragDrop;
|
|
layoutPanel.SetGridSize(gridSize);
|
|
|
|
return layoutPanel;
|
|
}
|
|
|
|
private TToggleHeaderPanel CreateHeader(App4Options.Group group)
|
|
{
|
|
var width = (TileLayoutPanel.TILE_SIZE + TileLayoutPanel.TILE_PADDING);
|
|
|
|
var headerPanel = new TToggleHeaderPanel();
|
|
headerPanel.ContextMenuStrip = groupMenuStrip;
|
|
headerPanel.Height = 20;
|
|
headerPanel.Padding = new Padding(0, 0, 0, 0);
|
|
headerPanel.Width = (group.GridSize.Width * width);
|
|
headerPanel.Title = group.Title;
|
|
headerPanel.IsOpen = group.IsOpen;
|
|
|
|
return headerPanel;
|
|
}
|
|
|
|
private TilePanel CreateTile(App4Options.Item item)
|
|
{
|
|
var tilePanel = new TilePanel();
|
|
tilePanel.ContextMenuStrip = tileMenuStrip;
|
|
tilePanel.Dock = DockStyle.Fill;
|
|
tilePanel.Margin = new Padding(0, 0, 3, 3);
|
|
tilePanel.Padding = new Padding(0);
|
|
|
|
tilePanel.MouseClick += TilePanel_MouseClick;
|
|
tilePanel.MouseDoubleClick += TilePanel_MouseClick;
|
|
tilePanel.OnFileDrop += TilePanel_OnFileDrop;
|
|
|
|
this.UpdateTile(tilePanel, item);
|
|
|
|
return tilePanel;
|
|
}
|
|
|
|
private App4Options.Item GetTileInfo(object sender)
|
|
{
|
|
App4Options.Item result = null;
|
|
|
|
if (sender is TilePanel)
|
|
{
|
|
var panel = (sender as TilePanel);
|
|
result = this.CurrentSession.FindById(panel.TileId);
|
|
}
|
|
else if (sender is ToolStripMenuItem)
|
|
{
|
|
var menuItem = (sender as ToolStripMenuItem);
|
|
if (menuItem.Tag == null)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
if (string.IsNullOrWhiteSpace(menuItem.Tag.ToString()))
|
|
{
|
|
return null;
|
|
}
|
|
|
|
if (!Guid.TryParse(menuItem.Tag.ToString(), out var tileId))
|
|
{
|
|
return null;
|
|
}
|
|
|
|
result = this.CurrentSession.FindById(tileId);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
private void UpdateTile(TilePanel tilePanel, App4Options.Item item)
|
|
{
|
|
tilePanel.TileId = item.Id;
|
|
tilePanel.Title = item.Title;
|
|
tilePanel.IsGroup = item.IsGroup;
|
|
|
|
if (item.IsGroup)
|
|
{
|
|
var iconSize = this.CurrentSession.ShowBigIcons ? 24 : 16;
|
|
|
|
tilePanel.LargeIcon = AppResource.folder_32;
|
|
tilePanel.TileContextMenu = new ContextMenuStrip();
|
|
tilePanel.TileContextMenu!.ImageScalingSize = new Size(iconSize, iconSize);
|
|
|
|
this.UpdateContextMenu(tilePanel.TileContextMenu, item.Items);
|
|
}
|
|
else
|
|
{
|
|
tilePanel.LargeIcon = RyzStudio.IO.File.GetIcon(item.ResolvedTargetPath);
|
|
tilePanel.TileContextMenu = null;
|
|
}
|
|
}
|
|
|
|
private ContextMenuStrip UpdateContextMenu(ContextMenuStrip contextMenu, List<App4Options.Item> items)
|
|
{
|
|
contextMenu.Items.Clear();
|
|
|
|
foreach (var item in items ?? new List<App4Options.Item>())
|
|
{
|
|
var subItemMenuItem = new ToolStripMenuItem()
|
|
{
|
|
Text = item.Title,
|
|
Image = RyzStudio.IO.File.GetIcon(item.ResolvedTargetPath),
|
|
Tag = item.Id
|
|
};
|
|
subItemMenuItem.Click += TileMenuItem_MouseClick;
|
|
|
|
contextMenu.Items.Add(subItemMenuItem);
|
|
}
|
|
|
|
return contextMenu;
|
|
}
|
|
|
|
private async void LayoutPanel_DragDrop(object sender, DragEventArgs e)
|
|
{
|
|
if (!e.Data.TryGetData<TilePanel>(out var tilePanel))
|
|
{
|
|
return;
|
|
}
|
|
|
|
var tableLayout = (sender as TileLayoutPanel);
|
|
|
|
var point = tableLayout.PointToClient(new Point(e.X, e.Y));
|
|
var newPosition = tableLayout.GetCellFromPoint(new Point(point.X, point.Y));
|
|
|
|
var groupInfo = this.CurrentSession.Groups.Where(x => x.Id == tableLayout.GroupId).FirstOrDefault();
|
|
if (groupInfo == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var newGridPosition = new Point(newPosition.X, newPosition.Y);
|
|
if (groupInfo.Items.Where(x => x.Position == newGridPosition).Any())
|
|
{
|
|
// Position already occupied
|
|
return;
|
|
}
|
|
|
|
await Task.Run(() =>
|
|
{
|
|
var foundTileInfo = this.CurrentSession.FindById(tilePanel.TileId);
|
|
foundTileInfo.Position = newGridPosition;
|
|
|
|
this.Controls.Remove(tilePanel);
|
|
|
|
tableLayout.AddTilePanel(tilePanel, newPosition.X, newPosition.Y);
|
|
});
|
|
|
|
_fileSessionManager.HasChanged = true;
|
|
}
|
|
|
|
|
|
private void TilePanel_MouseClick(object sender, MouseEventArgs e)
|
|
{
|
|
var tilePanel = (sender as TilePanel);
|
|
|
|
var tileInfo = this.GetTileInfo(sender);
|
|
if (tileInfo == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (e.Button == MouseButtons.Left)
|
|
{
|
|
if (tilePanel.IsGroup)
|
|
{
|
|
tilePanel.TileContextMenu?.Show(tilePanel, e.Location);
|
|
}
|
|
else
|
|
{
|
|
Execute(tileInfo);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
|
|
}
|
|
}
|
|
|
|
private void TileMenuItem_MouseClick(object sender, EventArgs e)
|
|
{
|
|
var tileInfo = this.GetTileInfo(sender);
|
|
if (tileInfo == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
Execute(tileInfo);
|
|
}
|
|
|
|
private async Task TilePanel_OnFileDrop(TilePanel sender, Keys keys, List<string> paths)
|
|
{
|
|
await Task.Run(() =>
|
|
{
|
|
var tileInfo = this.CurrentSession.FindById(sender.TileId);
|
|
|
|
// Append
|
|
if (keys.HasFlag(Keys.Shift))
|
|
{
|
|
if (tileInfo.IsGroup)
|
|
{
|
|
this.AddToFolder(tileInfo, paths, true);
|
|
}
|
|
else
|
|
{
|
|
var newTileInfo = tileInfo.CopyOf();
|
|
|
|
tileInfo.Title = "New Folder";
|
|
tileInfo.IsGroup = true;
|
|
tileInfo.TargetPath = string.Empty;
|
|
tileInfo.StartPath = string.Empty;
|
|
tileInfo.Argument = string.Empty;
|
|
tileInfo.RunAsAdmin = false;
|
|
|
|
tileInfo.Items.Clear();
|
|
tileInfo.Items.Add(newTileInfo);
|
|
|
|
this.AddToFolder(tileInfo, paths, true);
|
|
|
|
tileInfo.ResolvePaths();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (paths.Count <= 1)
|
|
{
|
|
tileInfo.IsGroup = false;
|
|
tileInfo.TargetPath = paths[0];
|
|
tileInfo.StartPath = string.Empty;
|
|
tileInfo.Argument = string.Empty;
|
|
tileInfo.RunAsAdmin = false;
|
|
|
|
tileInfo.Items.Clear();
|
|
tileInfo.ResolvePaths();
|
|
|
|
tileInfo.Title = RyzStudio.IO.File.GetName(tileInfo.ResolvedTargetPath);
|
|
}
|
|
else
|
|
{
|
|
tileInfo.Title = "New Folder";
|
|
tileInfo.IsGroup = true;
|
|
tileInfo.TargetPath = string.Empty;
|
|
tileInfo.StartPath = string.Empty;
|
|
tileInfo.Argument = string.Empty;
|
|
tileInfo.RunAsAdmin = false;
|
|
|
|
tileInfo.Items.Clear();
|
|
|
|
this.AddToFolder(tileInfo, paths, false);
|
|
|
|
tileInfo.ResolvePaths();
|
|
}
|
|
}
|
|
|
|
this.UpdateTile(sender, tileInfo);
|
|
});
|
|
|
|
_fileSessionManager.HasChanged = true;
|
|
}
|
|
|
|
private void Execute(App4Options.Item model)
|
|
{
|
|
if (model == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (model.IsGroup)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (this.CurrentSession.HideOnExecute)
|
|
{
|
|
this.Visible = false;
|
|
}
|
|
|
|
RyzStudio.Diagnostics.Process.Execute(model.ResolvedTargetPath, model.ResolvedStartPath, model.ResolvedArgument, model.WindowStyle, model.RunAsAdmin);
|
|
}
|
|
|
|
}
|
|
} |