/**
* Grasscutter Tools
* Copyright (C) 2022 jie65535
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
*
**/
using System;
using System.Drawing;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using GrasscutterTools.Game;
using GrasscutterTools.Pages;
using GrasscutterTools.Properties;
using GrasscutterTools.Utils;
namespace GrasscutterTools.Forms
{
public partial class FormMain : Form
{
#region - 初始化 Init -
public FormMain()
{
Console.WriteLine("FormMain ctor enter");
InitializeComponent();
Icon = Resources.IconGrasscutter;
if (DesignMode) return;
try
{
// 还原窗体位置
if (Settings.Default.MainFormLocation != default)
{
StartPosition = FormStartPosition.Manual;
Location = Settings.Default.MainFormLocation;
Console.WriteLine("Restore window location: " + Location.ToString());
}
// 还原窗体大小
if (Settings.Default.MainFormSize != default)
{
Size = Settings.Default.MainFormSize;
Console.WriteLine("Restore window size: " + Size.ToString());
}
// 初始化页面
InitPages();
// 恢复自动复制选项状态
ChkAutoCopy.Checked = Settings.Default.AutoCopy;
}
catch (Exception ex)
{
MessageBox.Show(Resources.SettingLoadError + ex.Message, Resources.Error, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
Console.WriteLine("FormMain ctor completed");
}
///
/// 初始化并创建所有页面
///
private void InitPages()
{
Console.WriteLine("InitPages enter");
TCMain.SuspendLayout();
var ph = CreatePage();
ph.OnLanguageChanged = () => FormMain_Load(this, EventArgs.Empty);
TPHome.Controls.Add(ph);
var poc = CreatePage();
poc.ShowTipInRunButton = msg => ShowTip(msg, BtnInvokeOpenCommand);
TPRemoteCall.Controls.Add(poc);
TPCustom.Controls.Add(CreatePage());
TPArtifact.Controls.Add(CreatePage());
TPSpawn.Controls.Add(CreatePage());
TPItem.Controls.Add(CreatePage());
TPAvatar.Controls.Add(CreatePage());
TPWeapon.Controls.Add(CreatePage());
TPManage.Controls.Add(CreatePage());
TPMail.Controls.Add(CreatePage());
TPQuest.Controls.Add(CreatePage());
TPScene.Controls.Add(CreatePage());
TPAbout.Controls.Add(CreatePage());
TCMain.ResumeLayout();
Console.WriteLine("InitPages completed");
}
///
/// 创建指定类型页面
///
/// 页面类型,必须继承BasePage
/// 页面实例
private T CreatePage() where T : BasePage, new()
{
var page = new T
{
SetCommand = SetCommand,
RunCommands = RunCommands,
GetCommand = () => CmbCommand.Text,
Dock = DockStyle.Fill,
};
return page;
}
///
/// 窗体载入时触发(切换语言时会重新载入)
///
private void FormMain_Load(object sender, EventArgs e)
{
Text += " - by jie65535 - v" + Common.AppVersion.ToString(3);
#if DEBUG
Text += "-debug";
#endif
if (DesignMode) return;
// 加载游戏ID资源
GameData.LoadResources();
// 遍历每一个页面重新加载
foreach (TabPage tp in TCMain.Controls)
{
if (tp.Controls.Count > 0 && tp.Controls[0] is BasePage page)
page.OnLoad();
}
}
///
/// 窗口关闭后触发
///
private void FormMain_FormClosed(object sender, FormClosedEventArgs e)
{
Console.WriteLine("FormMain FormClosed enter");
// 遍历每一个页面,通知关闭
foreach (TabPage tp in TCMain.Controls)
{
if (tp.Controls.Count > 0 && tp.Controls[0] is BasePage page)
page.OnClosed();
}
// 保存当前设置
SaveSettings();
Console.WriteLine("FormMain FormClosed completed");
}
///
/// 保存设置
///
private void SaveSettings()
{
try
{
// 记录界面状态
Settings.Default.AutoCopy = ChkAutoCopy.Checked;
Settings.Default.MainFormLocation = Location;
// 如果命令窗口已经弹出了,则不要保存多余的高度
if (TxtCommandRunLog != null)
Settings.Default.MainFormSize = new Size(Width, Height - TxtCommandRunLogMinHeight);
else
Settings.Default.MainFormSize = Size;
// 保存设置
Settings.Default.Save();
}
catch (Exception ex)
{
MessageBox.Show(Resources.SettingSaveError + ex.Message, Resources.Error, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
#endregion - 初始化 Init -
#region - 命令 Command -
///
/// 设置命令
///
/// 命令
private void SetCommand(string command)
{
var oldCommand = CmbCommand.Text;
CmbCommand.Text = (ModifierKeys == Keys.Shift) ? $"{oldCommand} | {command}" : command;
if (ChkAutoCopy.Checked)
CopyCommand();
AddCommandToList(command);
if (ModifierKeys == Keys.Control)
{
OnOpenCommandInvoke();
}
else if (ModifierKeys == Keys.Alt)
{
OnOpenCommandInvoke();
CmbCommand.Text = oldCommand;
}
}
///
/// 添加命令到执行记录
///
private void AddCommandToList(string command = "")
{
if (string.IsNullOrEmpty(command))
command = CmbCommand.Text;
if (!string.IsNullOrEmpty(command))
{
if (CmbCommand.Items.Count > 19)
CmbCommand.Items.RemoveAt(0);
CmbCommand.Items.Add(command);
}
}
///
/// 设置带参数的命令
///
/// 命令
/// 参数
private void SetCommand(string command, string args)
{
if (Settings.Default.IsIncludeUID)
SetCommand($"{command} @{Settings.Default.Uid} {args.Trim()}");
else
SetCommand($"{command} {args.Trim()}");
}
///
/// 点击复制按钮时触发
///
private async void BtnCopy_Click(object sender, EventArgs e)
{
CopyCommand();
await UIUtil.ButtonComplete(BtnCopy);
}
///
/// 复制命令
///
private void CopyCommand()
{
if (!string.IsNullOrEmpty(CmbCommand.Text))
Clipboard.SetText(CmbCommand.Text);
}
///
/// 在命令行内按下回车时直接执行
///
private void TxtCommand_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter) OnOpenCommandInvoke();
}
///
/// 开放命令执行时触发
///
private void OnOpenCommandInvoke()
{
BtnInvokeOpenCommand_Click(BtnInvokeOpenCommand, EventArgs.Empty);
}
///
/// 点击执行开放命令按钮时触发
///
private async void BtnInvokeOpenCommand_Click(object sender, EventArgs e)
{
if (!BtnInvokeOpenCommand.Enabled) return;
var cmd = CmbCommand.Text;
if (cmd.Length < 2)
{
ShowTip(Resources.CommandContentCannotBeEmpty, CmbCommand);
return;
}
if (cmd.IndexOf('|') == -1)
await RunCommands(FormatCommand(cmd));
else
await RunCommands(cmd.Split('|').Select(it => FormatCommand(it)).ToArray());
}
///
/// 格式化命令
/// (去除收尾空白,替换换行)
///
/// 原始输入
/// 格式化后可执行命令
private string FormatCommand(string raw)
{
return raw.Trim().Replace("\\r", "\r").Replace("\\n", "\n");
}
///
/// 运行命令
///
/// 命令列表
/// 是否执行成功
private async Task RunCommands(params string[] commands)
{
if (Common.OC == null || !Common.OC.CanInvoke)
{
ShowTip(Resources.RequireOpenCommandTip, BtnInvokeOpenCommand);
TCMain.SelectedTab = TPRemoteCall;
return false;
}
ExpandCommandRunLog();
try
{
BtnInvokeOpenCommand.Enabled = false;
BtnInvokeOpenCommand.Cursor = Cursors.WaitCursor;
int i = 0;
foreach (var command in commands)
{
TxtCommandRunLog.AppendText(">");
TxtCommandRunLog.AppendText(command);
if (commands.Length > 1)
TxtCommandRunLog.AppendText($" ({++i}/{commands.Length})");
TxtCommandRunLog.AppendText(Environment.NewLine);
var cmd = command.TrimStart('/');
try
{
var msg = await Common.OC.Invoke(cmd);
TxtCommandRunLog.AppendText(string.IsNullOrEmpty(msg) ? "OK" : msg);
TxtCommandRunLog.AppendText(Environment.NewLine);
}
catch (Exception ex)
{
TxtCommandRunLog.AppendText("Error: ");
TxtCommandRunLog.AppendText(ex.Message);
TxtCommandRunLog.AppendText(Environment.NewLine);
MessageBox.Show(ex.Message, Resources.Error, MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
TxtCommandRunLog.ScrollToCaret();
}
}
finally
{
BtnInvokeOpenCommand.Cursor = Cursors.Default;
BtnInvokeOpenCommand.Enabled = true;
}
return true;
}
///
/// 命令日志最小高度
///
private const int TxtCommandRunLogMinHeight = 150;
///
/// 命令日志文本框
///
private TextBox TxtCommandRunLog;
///
/// 展开命令记录(可重入)
///
private void ExpandCommandRunLog()
{
if (GrpCommand.Height < TxtCommandRunLogMinHeight)
{
if (WindowState == FormWindowState.Maximized)
WindowState = FormWindowState.Normal;
TCMain.Anchor &= ~AnchorStyles.Bottom;
GrpCommand.Anchor |= AnchorStyles.Top;
Size = new Size(Width, Height + TxtCommandRunLogMinHeight);
MinimumSize = new Size(MinimumSize.Width, MinimumSize.Height + TxtCommandRunLogMinHeight);
TCMain.Anchor |= AnchorStyles.Bottom;
GrpCommand.Anchor &= ~AnchorStyles.Top;
}
if (TxtCommandRunLog == null)
{
TxtCommandRunLog = new TextBox
{
Anchor = AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Right | AnchorStyles.Bottom,
Multiline = true,
Font = new Font("Consolas", 9F),
Location = new Point(BtnInvokeOpenCommand.Left, BtnInvokeOpenCommand.Bottom + 6),
Size = new Size(GrpCommand.Width - BtnInvokeOpenCommand.Left * 2, TxtCommandRunLogMinHeight),
ReadOnly = true,
BackColor = Color.White,
ScrollBars = ScrollBars.Vertical,
};
GrpCommand.Controls.Add(TxtCommandRunLog);
}
}
#endregion - 命令 Command -
#region - 通用 General -
///
/// 窗口按键按下时触发
///
private void FormMain_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.F5)
{
// F5 为执行命令
OnOpenCommandInvoke();
}
}
///
/// 提示气泡对象
///
private readonly ToolTip TTip = new ToolTip();
///
/// 在指定控件上显示提示气泡
///
/// 消息
/// 控件
private void ShowTip(string message, Control control)
{
TTip.Show(message, control, 0, control.Size.Height, 3000);
}
#endregion - 通用 General -
}
}