This repository has been archived on 2024-08-06. You can view files and clone it, but cannot push or open issues or pull requests.
linear-app-launcher/MainForm.cs
Ray 2e3b2998e7 Fixed file session manager
Added has-changed detection flag
Fixed dialog result null-value
Changed session manager event names
2024-07-05 22:43:19 +01:00

810 lines
25 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 FizzyLauncher.Models;
using RyzStudio.Windows.Forms;
using RyzStudio.Windows.ThemedForms.ButtonTextBox;
using RyzStudio.Windows.TileForms;
namespace FizzyLauncher
{
public partial class MainForm : Form
{
private readonly FileSessionManager _fileSessionManager;
private bool _isBusy = false;
private bool _requestExit = false;
public MainForm()
{
InitializeComponent();
_fileSessionManager = new 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;
//tileContainer1.OnColumnSizeChanged += tileContainer1_OnSizeChanged;
notifyIcon1.Text = System.Windows.Forms.Application.ProductName;
this.AutoScaleMode = AutoScaleMode.None;
//this.StartPosition = FormStartPosition.WindowsDefaultBounds;
//this.Visible = false;
}
protected async override void OnShown(EventArgs e)
{
base.OnShown(e);
var args = RyzStudio.Windows.Forms.Application.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(System.Windows.Forms.Application.ExecutablePath, "jsonfig");
}
if (!string.IsNullOrWhiteSpace(jsonfigFilename) && File.Exists(jsonfigFilename))
{
await _fileSessionManager.OpenSession(jsonfigFilename);
}
else
{
this.CurrentSession = new AppOptions();
InvalidateOptions();
//UIControl.SetVisible(this, true);
}
}
protected async override void OnClosing(CancelEventArgs e)
{
base.OnClosing(e);
if (this.CurrentSession == null)
{
this.CurrentSession = new AppOptions();
}
if (this.CurrentSession.HideOnClose && !_requestExit)
{
this.Visible = !this.Visible;
e.Cancel = true;
return;
}
_requestExit = false;
await _fileSessionManager.CloseSession();
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;
System.Windows.Forms.Application.Exit();
break;
default:
break;
}
base.WndProc(ref m);
}
public AppOptions CurrentSession { get; set; } = null;
private void InvalidateOptions()
{
/// 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.HotKey.ModifierCode, this.CurrentSession.HotKey.Key);
});
}
#endif
UIControl.SetTopMost(this, this.CurrentSession.AlwaysOnTop);
}
private void menuStrip1_MenuActivate(object sender, EventArgs e)
{
closeToolStripMenuItem.Enabled = (_fileSessionManager.SessionState != FileSessionManager.SessionStateEnum.Close);
saveToolStripMenuItem.Enabled = (_fileSessionManager.SessionState == FileSessionManager.SessionStateEnum.Open);
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 exitToolStripMenuItem2_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 void addGroupToolStripMenuItem_Click(object sender, EventArgs e)
{
AddNewTileGroup();
}
/// <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();
}
}
/// <summary>
/// View help
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void viewHelpToolStripMenuItem1_Click(object sender, EventArgs e)
{
RyzStudio.Diagnostics.Process.Execute(AppResource.AppHelpURL);
}
/// <summary>
/// About
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void aboutToolStripMenuItem1_Click(object sender, EventArgs e)
{
MessageBox.Show(System.Windows.Forms.Application.ProductName + " v" + System.Windows.Forms.Application.ProductVersion, "About", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
#endregion
#region Notification Icon
private void notifyIcon1_MouseClick(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
this.Visible = !this.Visible;
}
}
private void exitToolStripMenuItem1_Click(object sender, EventArgs e)
{
_requestExit = true;
this.Close();
}
#endregion
#region File Session Manager
private async Task<bool> fileSessionManager_OnNewSession(FileSessionManager sender)
{
return await Task.Run(() =>
{
var form = new NewForm();
if (form.ShowDialog() == DialogResult.OK)
{
var result = form.Result;
UIControl.Clear(flowLayoutPanel1);
this.CurrentSession.TilesPerRow = result.ColumnCount;
for (var i = 0; i < result.GroupCount; i++)
{
AddNewTileGroup();
}
}
AutoResize();
return true;
});
}
private async Task<bool> fileSessionManager_OnLoadSession(FileSessionManager sender, string filename)
{
return await Task.Run(async () =>
{
this.CurrentSession = RyzStudio.Text.Json.JsonSerialiser.DeserialiseFile<AppOptions>(filename);
if (this.CurrentSession == null)
{
MessageBox.Show("Unable to read session", "Load session");
return false;
}
if (this.CurrentSession == null)
{
this.CurrentSession = new AppOptions();
}
// Reposition + resize
if (!this.CurrentSession.StartPosition.IsEmpty)
{
UIControl.SetLocation(this, this.CurrentSession.StartPosition);
}
if (this.CurrentSession.Height > 0)
{
UIControl.SetClientHeight(this, this.CurrentSession.Height);
}
InvalidateOptions();
// Load tiles
await LoadTileGroups(this.CurrentSession.Groups);
AutoResize();
//UIControl.SetVisible(this, true);
UIControl.SetFocus(this);
return true;
});
}
private async Task<bool> fileSessionManager_OnSaveSession(FileSessionManager sender, string filename, bool showNotices)
{
if (string.IsNullOrWhiteSpace(filename))
{
return false;
}
if (!flowLayoutPanel1.Controls.OfType<TileContainer>().Any())
{
return true;
}
return await Task.Run(() =>
{
if (_isBusy)
{
return false;
}
_isBusy = true;
// update session
if (this.CurrentSession == null)
{
this.CurrentSession = new AppOptions();
}
this.CurrentSession.StartPosition = this.Location;
this.CurrentSession.Height = this.Height;
this.CurrentSession.Groups = new List<TileGroupModel>();
foreach (var container in flowLayoutPanel1.Controls.OfType<RyzStudio.Windows.TileForms.TileContainer>())
{
this.CurrentSession.Groups.Add((TileGroupModel)container.Tag);
}
var result = RyzStudio.Text.Json.JsonSerialiser.SerialiseFile(filename, this.CurrentSession);
if (result.IsSuccess)
{
if (showNotices)
{
MessageBox.Show("Session saved!", "Save session", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
else
{
MessageBox.Show(result.Message, "Save session");
_isBusy = false;
return false;
}
_isBusy = false;
return true;
});
}
private async Task<bool> fileSessionManager_OnClearSession(FileSessionManager sender)
{
await Task.Run(() =>
{
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 - " + System.Windows.Forms.Application.ProductName);
break;
case FileSessionManager.SessionStateEnum.Open:
UIControl.SetText(this, Path.GetFileNameWithoutExtension(filename) + " - " + System.Windows.Forms.Application.ProductName);
break;
case FileSessionManager.SessionStateEnum.Close:
UIControl.SetText(this, System.Windows.Forms.Application.ProductName);
break;
default:
break;
}
});
}
#endregion
#region Tile Container
/// <summary>
/// Add Tile
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void addGroupToolStripMenuItem1_Click(object sender, EventArgs e)
{
var container = UIControl.GetOwner<RyzStudio.Windows.TileForms.TileContainer>((ToolStripMenuItem)sender);
if (container == null)
{
return;
}
var form = new EditTileForm();
if (form.ShowDialog() == DialogResult.OK)
{
var result = form.Result;
var newCoord = container.GetNextCoord();
var newTile = new FizzyLauncher.Windows.Forms.TilePanel();
newTile.LoadInfo(result);
container.Add(newTile, newCoord.X, newCoord.Y);
_fileSessionManager.HasChanged = true;
};
}
/// <summary>
/// Add Tile Group
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void toolStripMenuItem4_Click(object sender, EventArgs e)
{
var container = UIControl.GetOwner<RyzStudio.Windows.TileForms.TileContainer>((ToolStripMenuItem)sender);
if (container == null)
{
return;
}
var form = new EditTileFolderForm();
if (form.ShowDialog() == DialogResult.OK)
{
var result = form.Result;
var newCoord = container.GetNextCoord();
var newTile = new FizzyLauncher.Windows.Forms.TilePanel();
newTile.LoadInfo(result);
container.Add(newTile, newCoord.X, newCoord.Y);
_fileSessionManager.HasChanged = true;
};
}
/// <summary>
/// Edit
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void editToolStripMenuItem_Click(object sender, EventArgs e)
{
var container = UIControl.GetOwner<RyzStudio.Windows.TileForms.TileContainer>((ToolStripMenuItem)sender);
if (container == null)
{
return;
}
var model = UIControl.GetTag<TileGroupModel>(container);
var form = new EditGroupForm(model);
if (form.ShowDialog() == DialogResult.OK)
{
var result = form.Result;
container.Title = result.Title;
container.Tag = result;
container.Invalidate();
_fileSessionManager.HasChanged = true;
};
}
/// <summary>
/// Row - Add Row
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void addRowToolStripMenuItem_Click(object sender, EventArgs e)
{
var container = UIControl.GetOwner<RyzStudio.Windows.TileForms.TileContainer>((ToolStripDropDownItem)sender);
if (container == null)
{
return;
}
container.AddRow();
_fileSessionManager.HasChanged = true;
}
/// <summary>
/// Row - Remove Row
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void removeRowToolStripMenuItem_Click(object sender, EventArgs e)
{
var container = UIControl.GetOwner<RyzStudio.Windows.TileForms.TileContainer>((ToolStripDropDownItem)sender);
if (container == null)
{
return;
}
container.RemoveRow();
_fileSessionManager.HasChanged = true;
}
/// <summary>
/// Move Top
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void topToolStripMenuItem_Click(object sender, EventArgs e)
{
var container = UIControl.GetOwner<RyzStudio.Windows.TileForms.TileContainer>((ToolStripDropDownItem)sender);
if (container == null)
{
return;
}
UIControl.MoveTop(flowLayoutPanel1, container);
_fileSessionManager.HasChanged = true;
}
/// <summary>
/// Move Up
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void upToolStripMenuItem_Click(object sender, EventArgs e)
{
var container = UIControl.GetOwner<RyzStudio.Windows.TileForms.TileContainer>((ToolStripDropDownItem)sender);
if (container == null)
{
return;
}
UIControl.MoveUp(flowLayoutPanel1, container);
_fileSessionManager.HasChanged = true;
}
/// <summary>
/// Move Down
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void downToolStripMenuItem_Click(object sender, EventArgs e)
{
var container = UIControl.GetOwner<RyzStudio.Windows.TileForms.TileContainer>((ToolStripDropDownItem)sender);
if (container == null)
{
return;
}
UIControl.MoveDown(flowLayoutPanel1, container);
_fileSessionManager.HasChanged = true;
}
/// <summary>
/// Move Bottom
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void bottomToolStripMenuItem_Click(object sender, EventArgs e)
{
var container = UIControl.GetOwner<RyzStudio.Windows.TileForms.TileContainer>((ToolStripDropDownItem)sender);
if (container == null)
{
return;
}
UIControl.MoveBottom(flowLayoutPanel1, container);
_fileSessionManager.HasChanged = true;
}
/// <summary>
/// Remove
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void removeToolStripMenuItem_Click(object sender, EventArgs e)
{
var container = UIControl.GetOwner<RyzStudio.Windows.TileForms.TileContainer>((ToolStripMenuItem)sender);
if (container == null)
{
return;
}
flowLayoutPanel1.Controls.Remove(container);
_fileSessionManager.HasChanged = true;
}
#endregion
private void AddNewTileGroup()
{
var group = new TileGroupModel();
group.Title = "New Group";
group.IsExpanded = true;
group.GridSize = new System.Drawing.Size(this.CurrentSession.TilesPerRow, 1);
var container = new RyzStudio.Windows.TileForms.TileContainer();
container.Title = group.Title;
container.IsOpen = group.IsExpanded;
container.TitleContextMenuStrip = tileContainerMenu1;
container.AutoSizeHeight = true;
container.Tag = group;
container.BackColor = Color.Orange;
UIControl.Add(flowLayoutPanel1, container);
container.AutoSize(group.GridSize.Width, group.GridSize.Height);
_fileSessionManager.HasChanged = true;
}
private void AutoResize()
{
if (flowLayoutPanel1.Controls.Count <= 0)
{
return;
}
var width = 0;
foreach (var item in flowLayoutPanel1.Controls.OfType<TileContainer>())
{
width = Math.Max(width, item.Width);
}
UIControl.SetClientWidth(this, width + panel1.Padding.Horizontal + this.Padding.Horizontal + SystemInformation.VerticalScrollBarWidth);
}
private async Task LoadTileGroups(List<TileGroupModel> groupList)
{
await Task.Run(() =>
{
UIControl.Clear(flowLayoutPanel1);
// Load groups
foreach (var item in groupList ?? new List<TileGroupModel>())
{
var panel = new RyzStudio.Windows.TileForms.TileContainer();
panel.Title = item.Title;
panel.IsOpen = item.IsExpanded;
panel.TitleContextMenuStrip = tileContainerMenu1;
panel.AutoSizeHeight = true;
panel.Tag = item;
panel.AutoSize(item.GridSize.Width, item.GridSize.Height);
UIControl.Add(flowLayoutPanel1, panel);
// Load tiles
foreach (var item2 in item.Items ?? new List<TileModel>())
{
var tile = new FizzyLauncher.Windows.Forms.TilePanel();
tile.LoadInfo(item2);
panel.Add(tile, item2.Position.X, item2.Position.Y);
}
}
});
}
}
}