|
|
|
@ -1,6 +1,7 @@ |
|
|
|
|
using System; |
|
|
|
|
using System.Windows; |
|
|
|
|
using System.Runtime.InteropServices; |
|
|
|
|
using System.IO; |
|
|
|
|
|
|
|
|
|
namespace smx_config |
|
|
|
|
{ |
|
|
|
@ -11,9 +12,17 @@ namespace smx_config |
|
|
|
|
[DllImport("SMX.dll", CallingConvention = CallingConvention.Cdecl)] |
|
|
|
|
private static extern void SMX_Internal_OpenConsole(); |
|
|
|
|
|
|
|
|
|
private System.Windows.Forms.NotifyIcon trayIcon; |
|
|
|
|
private MainWindow window; |
|
|
|
|
|
|
|
|
|
App() |
|
|
|
|
{ |
|
|
|
|
AppDomain.CurrentDomain.UnhandledException += UnhandledExceptionEventHandler; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
protected override void OnStartup(StartupEventArgs e) |
|
|
|
|
{ |
|
|
|
|
base.OnStartup(e); |
|
|
|
|
|
|
|
|
|
if(!SMX.SMX.DLLExists()) |
|
|
|
|
{ |
|
|
|
@ -38,6 +47,40 @@ namespace smx_config |
|
|
|
|
// we're running. |
|
|
|
|
Helpers.LoadSavedPanelAnimations(); |
|
|
|
|
SMX.SMX.LightsAnimation_SetAuto(true); |
|
|
|
|
|
|
|
|
|
CreateTrayIcon(); |
|
|
|
|
|
|
|
|
|
// Create the main window. |
|
|
|
|
ToggleMainWindow(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Open or close the main window. |
|
|
|
|
// |
|
|
|
|
// We don't create our UI until the first time it's opened, so we use |
|
|
|
|
// less memory when we're launched on startup. However, when we're minimized |
|
|
|
|
// back to the tray, we don't destroy the main window. WPF is just too |
|
|
|
|
// leaky to recreate the main window each time it's called due to internal |
|
|
|
|
// circular references. Instead, we just focus on minimizing CPU overhead. |
|
|
|
|
void ToggleMainWindow() |
|
|
|
|
{ |
|
|
|
|
if(window == null) |
|
|
|
|
{ |
|
|
|
|
window = new MainWindow(); |
|
|
|
|
window.Closed += MainWindowClosed; |
|
|
|
|
window.Show(); |
|
|
|
|
} |
|
|
|
|
else if(window.WindowState == WindowState.Minimized) |
|
|
|
|
{ |
|
|
|
|
window.WindowState = WindowState.Normal; |
|
|
|
|
window.Activate(); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
window.WindowState = WindowState.Minimized; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private void MainWindowClosed(object sender, EventArgs e) |
|
|
|
|
{ |
|
|
|
|
window = null; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private void UnhandledExceptionEventHandler(object sender, UnhandledExceptionEventArgs e) |
|
|
|
@ -50,13 +93,69 @@ namespace smx_config |
|
|
|
|
{ |
|
|
|
|
base.OnExit(e); |
|
|
|
|
|
|
|
|
|
// Shut down cleanly, to make sure we don't run any threaded callbacks during shutdown. |
|
|
|
|
Console.WriteLine("Application exiting"); |
|
|
|
|
if(CurrentSMXDevice.singleton == null) |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
// Remove the tray icon. |
|
|
|
|
if(trayIcon != null) |
|
|
|
|
{ |
|
|
|
|
trayIcon.Visible = false; |
|
|
|
|
trayIcon = null; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Shut down cleanly, to make sure we don't run any threaded callbacks during shutdown. |
|
|
|
|
if(CurrentSMXDevice.singleton != null) |
|
|
|
|
{ |
|
|
|
|
CurrentSMXDevice.singleton.Shutdown(); |
|
|
|
|
CurrentSMXDevice.singleton = null; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Create a tray icon. For some reason there's no WPF interface for this, |
|
|
|
|
// so we have to use Forms. |
|
|
|
|
void CreateTrayIcon() |
|
|
|
|
{ |
|
|
|
|
Stream iconStream = GetResourceStream(new Uri( "pack://application:,,,/Resources/window%20icon%20grey.ico")).Stream; |
|
|
|
|
System.Drawing.Icon icon = new System.Drawing.Icon(iconStream); |
|
|
|
|
|
|
|
|
|
trayIcon = new System.Windows.Forms.NotifyIcon(); |
|
|
|
|
trayIcon.Text = "StepManiaX"; |
|
|
|
|
trayIcon.Visible = true; |
|
|
|
|
|
|
|
|
|
// Show or hide the application window on click. |
|
|
|
|
trayIcon.Click += delegate (object sender, EventArgs e) { ToggleMainWindow(); }; |
|
|
|
|
trayIcon.DoubleClick += delegate (object sender, EventArgs e) { ToggleMainWindow(); }; |
|
|
|
|
|
|
|
|
|
CurrentSMXDevice.singleton.ConfigurationChanged += delegate(LoadFromConfigDelegateArgs args) { |
|
|
|
|
RefreshTrayIcon(args); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// Do the initial refresh. |
|
|
|
|
RefreshTrayIcon(CurrentSMXDevice.singleton.GetState(), true); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Refresh the tray icon when we're connected or disconnected. |
|
|
|
|
bool wasConnected; |
|
|
|
|
void RefreshTrayIcon(LoadFromConfigDelegateArgs args, bool force=false) |
|
|
|
|
{ |
|
|
|
|
if(trayIcon == null) |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
bool EitherControllerConnected = false; |
|
|
|
|
for(int pad = 0; pad < 2; ++pad) |
|
|
|
|
if(args.controller[pad].info.connected) |
|
|
|
|
EitherControllerConnected = true; |
|
|
|
|
|
|
|
|
|
// Skip the refresh if the connected state didn't change. |
|
|
|
|
if(wasConnected == EitherControllerConnected && !force) |
|
|
|
|
return; |
|
|
|
|
wasConnected = EitherControllerConnected; |
|
|
|
|
|
|
|
|
|
trayIcon.Text = EitherControllerConnected? "StepManiaX (connected)":"StepManiaX (disconnected)"; |
|
|
|
|
|
|
|
|
|
// Set the tray icon. |
|
|
|
|
string filename = EitherControllerConnected? "window%20icon.ico":"window%20icon%20grey.ico"; |
|
|
|
|
Stream iconStream = GetResourceStream(new Uri( "pack://application:,,,/Resources/" + filename)).Stream; |
|
|
|
|
trayIcon.Icon = new System.Drawing.Icon(iconStream); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|