jays2kings c52929f5fa Made keystrokes more akin to phyiscally pressing (holding down actually repeats the key), removed repeat option due to this
Edit Profile button shows new if controller has no profile, other small UI changes
2014-05-06 14:49:18 -04:00

544 lines
22 KiB
C#

using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using DS4Control;
using System.Threading;
using System.IO;
using System.Reflection;
using System.Collections.Generic;
namespace ScpServer
{
public partial class ScpForm : Form
{
private DS4Control.Control rootHub;
delegate void LogDebugDelegate(DateTime Time, String Data);
protected void LogDebug(DateTime Time, String Data)
{
if (lvDebug.InvokeRequired)
{
LogDebugDelegate d = new LogDebugDelegate(LogDebug);
try
{
this.Invoke(d, new Object[] { Time, Data });
}
catch { }
}
else
{
String Posted = Time.ToString("O");
lvDebug.Items.Add(new ListViewItem(new String[] { Posted, Data })).EnsureVisible();
//Added alternative
lbLastMessage.Text = Data;
}
}
protected void ShowNotification(object sender, DebugEventArgs args)
{
notifyIcon1.BalloonTipText = args.Data;
notifyIcon1.BalloonTipTitle = "DS4Windows";
notifyIcon1.ShowBalloonTip(1);
}
protected void Form_Resize(object sender, EventArgs e)
{
if (FormWindowState.Minimized == this.WindowState)
{
notifyIcon1.Visible = true;
this.Hide();
this.ShowInTaskbar = false;
}
else if (FormWindowState.Normal == this.WindowState)
{
notifyIcon1.Visible = false;
this.Show();
this.ShowInTaskbar = true;
}
//Added last message alternative
if (this.Height > 220)
lbLastMessage.Visible = false;
else lbLastMessage.Visible = true;
for (int i = 0; i < 4; i++)
if (this.Width > 665)
protexts[i].Visible = true;
else
protexts[i].Visible = false;
}
protected Label[] Pads;
protected ComboBox[] cbs;
protected Button[] ebns;
protected Button[] dbns;
protected Label[] protexts;
protected ToolStripMenuItem[] shortcuts;
public ScpForm()
{
InitializeComponent();
ThemeUtil.SetTheme(lvDebug);
Pads = new Label[4] { lbPad1, lbPad2, lbPad3, lbPad4 };
cbs = new ComboBox[4] { cBController1, cBController2, cBController3, cBController4 };
ebns = new Button[4] { bnEditC1, bnEditC2, bnEditC3, bnEditC4 };
dbns = new Button[4] { bnDeleteC1, bnDeleteC2, bnDeleteC3, bnDeleteC4 };
protexts = new Label[4] { lbSelPro1, lbSelPro2, lbSelPro3, lbSelPro4 };
shortcuts = new ToolStripMenuItem[4] { (ToolStripMenuItem)notifyIcon1.ContextMenuStrip.Items[0],
(ToolStripMenuItem)notifyIcon1.ContextMenuStrip.Items[1],
(ToolStripMenuItem)notifyIcon1.ContextMenuStrip.Items[2],
(ToolStripMenuItem)notifyIcon1.ContextMenuStrip.Items[3] };
foreach (ToolStripMenuItem t in shortcuts)
t.DropDownItemClicked += Profile_Changed_Menu;
}
protected void Form_Load(object sender, EventArgs e)
{
Icon = Properties.Resources.DS4;
notifyIcon1.Icon = Properties.Resources.DS4;
rootHub = new DS4Control.Control();
rootHub.Debug += On_Debug;
Log.GuiLog += On_Debug;
Log.TrayIconLog += ShowNotification;
// tmrUpdate.Enabled = true; TODO remove tmrUpdate and leave tick()
Global.Load();
hideDS4CheckBox.CheckedChanged -= hideDS4CheckBox_CheckedChanged;
hideDS4CheckBox.Checked = Global.getUseExclusiveMode();
hideDS4CheckBox.CheckedChanged += hideDS4CheckBox_CheckedChanged;
// New settings
this.Width = Global.getFormWidth();
this.Height = Global.getFormHeight();
startMinimizedCheckBox.CheckedChanged -= startMinimizedCheckBox_CheckedChanged;
startMinimizedCheckBox.Checked = Global.getStartMinimized();
startMinimizedCheckBox.CheckedChanged += startMinimizedCheckBox_CheckedChanged;
if (startMinimizedCheckBox.Checked)
{
this.WindowState = FormWindowState.Minimized;
Form_Resize(sender, e);
}
RefreshProfiles();
for (int i = 0; i < 4; i++)
{
Global.LoadProfile(i);
}
Global.ControllerStatusChange += ControllerStatusChange;
ControllerStatusChanged();
if (btnStartStop.Enabled)
btnStartStop_Clicked();
}
public void RefreshProfiles()
{
try
{
string[] profiles = System.IO.Directory.GetFiles(Directory.GetParent(Assembly.GetExecutingAssembly().Location).FullName + @"\Profiles\");
int cutoff = (Directory.GetParent(Assembly.GetExecutingAssembly().Location).FullName + @"\Profiles\").Length;
List<string> profilenames = new List<string>();
foreach (String s in profiles)
if (s.EndsWith(".xml"))
profilenames.Add(s.Substring(cutoff, s.Length - 4 - cutoff));
for (int i = 0; i < 4; i++)
{
cbs[i].Items.Clear();
shortcuts[i].DropDownItems.Clear();
string[] profileA = Global.getAProfile(i).Split('\\');
string filename = profileA[profileA.Length - 1];
cbs[i].Items.AddRange(profilenames.ToArray());
foreach (string s in profilenames)
shortcuts[i].DropDownItems.Add(s);
for (int j = 0; j < cbs[i].Items.Count; j++)
if (cbs[i].Items[j] + ".xml" == filename)
{
cbs[i].SelectedIndex = j;
((ToolStripMenuItem)shortcuts[i].DropDownItems[j]).Checked = true;
Global.setAProfile(i, cbs[i].Text);
shortcuts[i].Text = "Edit Profile for Controller " + (i + 1);
ebns[i].Text = "Edit";
break;
}
else
{
cbs[i].Text = "(No Profile Found)";
shortcuts[i].Text = "Make Profile for Controller " + (i + 1);
ebns[i].Text = "New";
}
cbs[i].Items.Add("+New Profile");
shortcuts[i].DropDownItems.Add("-");
shortcuts[i].DropDownItems.Add("+New Profile");
}
}
catch (DirectoryNotFoundException)
{
System.IO.Directory.CreateDirectory(Directory.GetParent(Assembly.GetExecutingAssembly().Location).FullName + @"\Profiles\");
for (int i = 0; i < 4; i++)
{
cbs[i].Items.Add("");
cbs[i].SelectedIndex = 0;
cbs[i].Items.Add("+New Profile");
}
}
}
protected void Form_Close(object sender, FormClosingEventArgs e)
{
Global.setFormWidth(this.Width);
Global.setFormHeight(this.Height);
Global.Save();
rootHub.Stop();
}
protected void btnStartStop_Click(object sender, EventArgs e)
{
btnStartStop_Clicked();
}
protected void btnStartStop_Clicked()
{
if (btnStartStop.Text == Properties.Resources.Start
&& rootHub.Start())
btnStartStop.Text = Properties.Resources.Stop;
else if (btnStartStop.Text == Properties.Resources.Stop
&& rootHub.Stop())
btnStartStop.Text = Properties.Resources.Start;
}
protected void btnStop_Click(object sender, EventArgs e)
{
if (rootHub.Stop())
{
btnStartStop.Enabled = true;
btnStop.Enabled = false;
}
}
protected void btnClear_Click(object sender, EventArgs e)
{
lvDebug.Items.Clear();
//Added alternative
lbLastMessage.Text = string.Empty;
}
protected override void WndProc(ref Message m)
{
try
{
if (m.Msg == ScpDevice.WM_DEVICECHANGE)
{
Int32 Type = m.WParam.ToInt32();
lock (this)
{
rootHub.HotPlug();
}
}
}
catch { }
base.WndProc(ref m);
}
delegate void ControllerStatusChangedDelegate(object sender, EventArgs e);
protected void ControllerStatusChange(object sender, EventArgs e)
{
if (InvokeRequired)
Invoke(new ControllerStatusChangedDelegate(ControllerStatusChange), new object[] { sender, e });
else
ControllerStatusChanged();
}
protected void ControllerStatusChanged()
{
// If controllers are detected, but not checked, automatically check #1
//bool checkFirst = true;
String tooltip = "DS4Windows";
for (Int32 Index = 0; Index < Pads.Length; Index++)
{
Pads[Index].Text = rootHub.getDS4ControllerInfo(Index);
if (Pads[Index].Text != String.Empty)
{
Pads[Index].Enabled = true;
cbs[Index].Enabled = true;
ebns[Index].Enabled = true;
dbns[Index].Enabled = true;
protexts[Index].Enabled = true;
shortcuts[Index].Enabled = true;
// As above
//if (checkFirst && (Pads[Index].Checked && Index != 0))
// checkFirst = false;
}
else
{
Pads[Index].Text = "Disconnected";
Pads[Index].Enabled = false;
cbs[Index].Enabled = false;
ebns[Index].Enabled = false;
dbns[Index].Enabled = false;
protexts[Index].Enabled = false;
if (OptionsDialog[Index] != null)
OptionsDialog[Index].Close();
shortcuts[Index].Enabled = false;
// As above
//if (Index == 0)
// checkFirst = false;
}
if (rootHub.getShortDS4ControllerInfo(Index) != "None")
tooltip += "\n" + (Index + 1) + ": " + rootHub.getShortDS4ControllerInfo(Index); // Carefully stay under the 63 character limit.
}
btnClear.Enabled = lvDebug.Items.Count > 0;
// As above
//if (checkFirst && btnClear.Enabled)
// Pads[0].Checked = true;
notifyIcon1.Text = tooltip;
}
protected void On_Debug(object sender, DS4Control.DebugEventArgs e)
{
LogDebug(e.Time, e.Data);
}
private Options[] OptionsDialog = { null, null, null, null };
private void editButtons_Click(object sender, EventArgs e)
{
Button bn = (Button)sender;
int i = Int32.Parse(bn.Tag.ToString());
if (OptionsDialog[i] == null)
{
Options opt;
if (cbs[i].Text == "(No Profile Found)")
opt = OptionsDialog[i] = new Options(rootHub, i, "", this);
else
opt = OptionsDialog[i] = new Options(rootHub, i, cbs[i].Text, this);
opt.Text = "Options for Controller " + (i + 1);
opt.Icon = this.Icon;
opt.FormClosed += delegate
{
OptionsDialog[i] = null;
};
opt.Show();
}
}
private void editMenu_Click(object sender, EventArgs e)
{
ToolStripMenuItem em = (ToolStripMenuItem)sender;
int i = Int32.Parse(em.Tag.ToString());
if (OptionsDialog[i] == null)
{
if (em.Text == "Make Profile for Controller " + (i + 1))
{
Options opt = OptionsDialog[i] = new Options(rootHub, i, "", this);
opt.Text = "Options for Controller " + (i + 1);
opt.Icon = this.Icon;
opt.FormClosed += delegate
{
OptionsDialog[i] = null;
};
opt.Show();
}
else
foreach (ToolStripMenuItem t in em.DropDownItems)
if (((ToolStripMenuItem)t).Checked)
{
Options opt = OptionsDialog[i] = new Options(rootHub, i, ((ToolStripMenuItem)t).Text, this);
opt.Text = "Options for Controller " + (i + 1);
opt.Icon = this.Icon;
opt.FormClosed += delegate
{
OptionsDialog[i] = null;
};
opt.Show();
break;
}
}
}
private void Enable_Controls(int device, bool on)
{
ebns[device].Enabled = on;
dbns[device].Enabled = on;
cbs[device].Enabled = on;
shortcuts[device].Enabled = on;
}
private void deleteButtons_Click(object sender, EventArgs e)
{
Button bn = (Button)sender;
int tdevice = Int32.Parse(bn.Tag.ToString());
string filename = cbs[tdevice].Items[cbs[tdevice].SelectedIndex].ToString();
if (MessageBox.Show("\"" + filename + "\" cannot be restored.", "Delete Profile?", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes)
{
System.IO.File.Delete(Directory.GetParent(Assembly.GetExecutingAssembly().Location).FullName + @"\Profiles\" + filename + ".xml");
Global.setAProfile(tdevice, null);
RefreshProfiles();
}
}
private void hotkeysButton_Click(object sender, EventArgs e)
{
Hotkeys hotkeysForm = new Hotkeys();
hotkeysForm.Icon = this.Icon;
hotkeysForm.ShowDialog();
}
private void lnkControllers_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
System.Diagnostics.Process.Start("control", "joy.cpl");
}
private void hideDS4CheckBox_CheckedChanged(object sender, EventArgs e)
{
// Prevent the Game Controllers window from throwing an error when controllers are un/hidden
System.Diagnostics.Process[] rundll32 = System.Diagnostics.Process.GetProcessesByName("rundll32");
foreach (System.Diagnostics.Process rundll32Instance in rundll32)
foreach (System.Diagnostics.ProcessModule module in rundll32Instance.Modules)
if (module.FileName.Contains("joy.cpl"))
module.Dispose();
Global.setUseExclusiveMode(hideDS4CheckBox.Checked);
btnStartStop_Clicked();
btnStartStop_Clicked();
Global.Save();
}
private void startMinimizedCheckBox_CheckedChanged(object sender, EventArgs e)
{
Global.setStartMinimized(startMinimizedCheckBox.Checked);
Global.Save();
}
private void AboutButton_Click(object sender, EventArgs e)
{
AboutBox box = new AboutBox();
box.Icon = this.Icon;
box.ShowDialog();
}
private void lvDebug_ItemActivate(object sender, EventArgs e)
{
MessageBox.Show(((ListView)sender).FocusedItem.SubItems[1].Text, "Log");
}
private void Profile_Changed(object sender, EventArgs e)
{
ComboBox cb = (ComboBox)sender;
int tdevice = Int32.Parse(cb.Tag.ToString());
if (cb.Items[cb.Items.Count - 1].ToString() == "+New Profile")
{
if (cb.SelectedIndex < cb.Items.Count - 1)
{
for (int i = 0; i < shortcuts[tdevice].DropDownItems.Count; i++)
if (!(shortcuts[tdevice].DropDownItems[i] is ToolStripSeparator))
((ToolStripMenuItem)shortcuts[tdevice].DropDownItems[i]).Checked = false;
((ToolStripMenuItem)shortcuts[tdevice].DropDownItems[cb.SelectedIndex]).Checked = true;
shortcuts[tdevice].Text = "Edit Profile for Controller " + (tdevice + 1);
Global.setAProfile(tdevice, cb.Items[cb.SelectedIndex].ToString());
Global.Save();
Global.LoadProfile(tdevice);
}
else if (cb.SelectedIndex == cb.Items.Count - 1 && cb.Items.Count > 1) //if +New Profile selected
{
if (OptionsDialog[tdevice] == null)
{
Options opt = OptionsDialog[tdevice] = new Options(rootHub, tdevice, "", this);
opt.Text = "Options for Controller " + (tdevice + 1);
opt.Icon = this.Icon;
int i = tdevice;
opt.FormClosed += delegate
{
OptionsDialog[i] = null;
};
opt.Show();
}
}
if (cb.Text == "(No Profile Found)")
ebns[tdevice].Text = "New";
else
ebns[tdevice].Text = "Edit";
}
}
private void Profile_Changed_Menu(object sender, ToolStripItemClickedEventArgs e)
{
ToolStripMenuItem tS = (ToolStripMenuItem)sender;
int tdevice = Int32.Parse(tS.Tag.ToString());
if (!(e.ClickedItem is ToolStripSeparator))
if (e.ClickedItem != tS.DropDownItems[tS.DropDownItems.Count - 1]) //if +New Profile not selected
if (((ToolStripMenuItem)e.ClickedItem).Checked && OptionsDialog[tdevice] == null)
{
Options opt = OptionsDialog[tdevice] = new Options(rootHub, tdevice, e.ClickedItem.Text, this);
opt.Text = "Options for Controller " + (tdevice + 1);
opt.Icon = this.Icon;
int i = tdevice;
opt.FormClosed += delegate
{
OptionsDialog[i] = null;
};
opt.Show();
}
else
{
for (int i = 0; i < tS.DropDownItems.Count; i++)
if (!(shortcuts[tdevice].DropDownItems[i] is ToolStripSeparator))
((ToolStripMenuItem)tS.DropDownItems[i]).Checked = false;
((ToolStripMenuItem)e.ClickedItem).Checked = true;
shortcuts[tdevice].Text = "Edit Profile for Controller " + (tdevice + 1);
cbs[tdevice].SelectedIndex = tS.DropDownItems.IndexOf(e.ClickedItem);
Global.setAProfile(tdevice, e.ClickedItem.Text);
Global.Save();
Global.LoadProfile(tdevice);
}
else if (OptionsDialog[tdevice] == null) //if +New Profile selected
{
Options opt = OptionsDialog[tdevice] = new Options(rootHub, tdevice, "", this);
opt.Text = "Options for Controller " + (tdevice + 1);
opt.Icon = this.Icon;
int i = tdevice;
opt.FormClosed += delegate
{
OptionsDialog[i] = null;
};
opt.Show();
}
}
private void exitToolStripMenuItem_Click(object sender, EventArgs e)
{
this.Close();
}
private void openToolStripMenuItem_Click(object sender, EventArgs e)
{
notifyIcon_Click(sender, e);
}
private void notifyIcon_Click(object sender, EventArgs e)
{
this.Show();
WindowState = FormWindowState.Normal;
}
private void ScpForm_Move(object sender, EventArgs e)
{
}
}
public class ThemeUtil
{
[DllImport("UxTheme", CharSet = CharSet.Unicode, ExactSpelling = true)]
private static extern int SetWindowTheme(IntPtr hWnd, String appName, String partList);
public static void SetTheme(ListView lv)
{
try
{
SetWindowTheme(lv.Handle, "Explorer", null);
}
catch { }
}
public static void SetTheme(TreeView tv)
{
try
{
SetWindowTheme(tv.Handle, "Explorer", null);
}
catch { }
}
}
}