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 RokettoLaunch.DTOs.SaveFile; using RokettoLaunch.Forms; using RokettoLaunch.Windows.Forms; using RyzStudio; using RyzStudio.Windows.Forms; using RyzStudio.Windows.ThemedForms; using RyzStudio.Windows.ThemedForms.ButtonTextBox; namespace RokettoLaunch { public partial class MainForm : Form { private readonly IFileSessionManager _fileSessionManager; private App4Options currentSession = null; private bool isBusy = false; private bool requestExit = false; public MainForm() { InitializeComponent(); this.AutoScaleMode = AutoScaleMode.None; this.StartPosition = FormStartPosition.WindowsDefaultLocation; this.Text = Application.ProductName; _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; notifyIcon1.Text = Application.ProductName; } 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"); } 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) { this.Hide(); 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 { if (currentSession == null) { currentSession = new App4Options(); } return currentSession; } set => currentSession = value; } 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 /// /// New /// /// /// private async void NewToolStripMenuItem_Click(object sender, EventArgs e) { if (isBusy) { return; } await _fileSessionManager.NewSession(); } /// /// Open /// /// /// private async void OpenToolStripMenuItem_Click(object sender, EventArgs e) { if (isBusy) { return; } await _fileSessionManager.OpenSession(); } /// /// Close /// /// /// private async void CloseToolStripMenuItem_Click(object sender, EventArgs e) { if (isBusy) { return; } await _fileSessionManager.CloseSession(); } /// /// Save /// /// /// private async void SaveToolStripMenuItem_Click(object sender, EventArgs e) { if (isBusy) { return; } await _fileSessionManager.SaveSession(); } /// /// Save As /// /// /// private async void SaveAsToolStripMenuItem_Click(object sender, EventArgs e) { if (isBusy) { return; } await _fileSessionManager.SaveAsSession(); } /// /// Exit /// /// /// private void ExitToolStripMenuItem_Click(object sender, EventArgs e) { if (isBusy) { return; } requestExit = true; this.Close(); } /// /// Add group /// /// /// 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; } /// /// Show big icons /// /// /// private void ShowBigIconsToolStripMenuItem_Click(object sender, EventArgs e) { if (this.CurrentSession == null) { return; } this.CurrentSession.ShowBigIcons = !this.CurrentSession.ShowBigIcons; } /// /// Always on top /// /// /// private void AlwaysOnTopToolStripMenuItem_Click(object sender, EventArgs e) { if (this.CurrentSession == null) { return; } this.CurrentSession.AlwaysOnTop = !this.CurrentSession.AlwaysOnTop; this.TopMost = this.CurrentSession.AlwaysOnTop; } /// /// Options /// /// /// 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); } } /// /// View help /// /// /// private void ViewHelpToolStripMenuItem_Click(object sender, EventArgs e) { RyzStudio.Diagnostics.Process.Execute(AppResource.AppHelpURL); } /// /// About /// /// /// 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 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 fileSessionManager_OnLoadSession(FileSessionManager sender, string filename, int formatType) { var loadingForm = new 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()) { 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 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 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 /// /// Add Tile /// /// /// private void AddTileToolStripMenuItem_Click(object sender, EventArgs e) { var panel = UIControl.GetOwner((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; } /// /// Add Folder /// /// /// private void AddFolderToolStripMenuItem_Click(object sender, EventArgs e) { var panel = UIControl.GetOwner((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; } /// /// Edit /// /// /// private void EditGroupToolStripMenuItem_Click(object sender, EventArgs e) { var panel = UIControl.GetOwner((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 tableLayout = (TileLayoutPanel)panel.ToggleControl; var editGroupForm = new EditGroupForm(groupInfo); if (editGroupForm.ShowDialog() == DialogResult.OK) { var newGroupInfo = editGroupForm.Result; groupInfo.Title = newGroupInfo.Title; groupInfo.IsOpen = newGroupInfo.IsOpen; groupInfo.GridSize = newGroupInfo.GridSize; panel.Title = newGroupInfo.Title; panel.Invalidate(); tableLayout.SetGridSize(groupInfo.GridSize); _fileSessionManager.HasChanged = true; } } /// /// Duplicate /// /// /// private async void toolStripMenuItem5_Click(object sender, EventArgs e) { var panel = UIControl.GetOwner((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; } /// /// Move Top /// /// /// private void MoveTopToolStripMenuItem_Click(object sender, EventArgs e) { var panel = UIControl.GetOwner((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; } /// /// Move Up /// /// /// private void MoveUpToolStripMenuItem_Click(object sender, EventArgs e) { var panel = UIControl.GetOwner((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; } /// /// Move Down /// /// /// private void MoveDownToolStripMenuItem_Click(object sender, EventArgs e) { var panel = UIControl.GetOwner((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; } /// /// Move Bottom /// /// /// private void MoveBottomToolStripMenuItem_Click(object sender, EventArgs e) { var panel = UIControl.GetOwner((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; } /// /// Remove /// /// /// 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((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 /// /// Edit /// /// /// private void EditTileToolStripMenuItem_Click(object sender, EventArgs e) { var tilePanel = UIControl.GetOwner((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; } /// /// Copy To /// /// /// private async void CopyToTileToolStripMenuItem_Click(object sender, EventArgs e) { var tilePanel = UIControl.GetOwner((ToolStripMenuItem)sender); var tileInfo = this.GetTileInfo(tilePanel); if (tileInfo == null) { return; } var groups = this.CurrentSession.Groups.Select(x => x.Title)?.ToList() ?? new List(); 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().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; } } /// /// Remove /// /// /// private void RemoveTileToolStripMenuItem_Click(object sender, EventArgs e) { var tilePanel = UIControl.GetOwner((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; header.IsOpen = groupInfo.IsOpen; UIControl.Add(flowLayoutPanel1, header); UIControl.Add(flowLayoutPanel1, tableLayout); foreach (var item in groupInfo.Items ?? new List()) { var tilePanel = CreateTile(item); tableLayout.AddTilePanel(tilePanel, item.Position.X, item.Position.Y); } tableLayout.SetGridSize(groupInfo.GridSize); } private void AddToFolder(App4Options.Item item, List 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 items) { contextMenu.Items.Clear(); foreach (var item in items ?? new List()) { 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(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 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); } } }