mirror of
https://github.com/hawkeye-stan/msfs-popout-panel-manager.git
synced 2024-11-22 05:40:11 +00:00
Version 3.3
This commit is contained in:
parent
973ebd3dd7
commit
a90077b44c
33 changed files with 551 additions and 178 deletions
|
@ -23,6 +23,7 @@ namespace MSFSPopoutPanelManager.FsConnector
|
|||
SIMSTOP,
|
||||
FLIGHTLOADED,
|
||||
VIEW,
|
||||
PAUSED
|
||||
PAUSED,
|
||||
NONE
|
||||
};
|
||||
}
|
||||
|
|
|
@ -5,13 +5,15 @@
|
|||
<AssemblyName>FsConnector</AssemblyName>
|
||||
<PackageId>MSFS 2020 Popout Panel Manager FsConnector</PackageId>
|
||||
<Product>MSFS 2020 Popout Panel Manager FsConnector</Product>
|
||||
<Version>3.2.0</Version>
|
||||
<Version>3.3.0.0</Version>
|
||||
<Authors>Stanley Kwok</Authors>
|
||||
<Company>Stanley Kwok</Company>
|
||||
<Copyright>Stanley Kwok 2021</Copyright>
|
||||
<PackageProjectUrl>https://github.com/hawkeye-stan/msfs-popout-panel-manager</PackageProjectUrl>
|
||||
<RootNamespace>MSFSPopoutPanelManager.FsConnector</RootNamespace>
|
||||
<Platforms>x64;AnyCPU</Platforms>
|
||||
<AssemblyVersion>3.3.0.0</AssemblyVersion>
|
||||
<FileVersion>3.3.0.0</FileVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
@ -19,7 +19,7 @@ namespace MSFSPopoutPanelManager.FsConnector
|
|||
public event EventHandler<EventArgs<dynamic>> OnReceivedData;
|
||||
public event EventHandler OnConnected;
|
||||
public event EventHandler OnDisconnected;
|
||||
public event EventHandler<EventArgs<SimConnectSystemEvent>> OnReceiveSystemEvent;
|
||||
public event EventHandler<EventArgs<Tuple<SimConnectSystemEvent, uint>>> OnReceiveSystemEvent;
|
||||
|
||||
public dynamic SimData { get; set; }
|
||||
|
||||
|
@ -183,12 +183,9 @@ namespace MSFSPopoutPanelManager.FsConnector
|
|||
private void HandleOnReceiveEvent(SimConnect sender, SIMCONNECT_RECV_EVENT data)
|
||||
{
|
||||
var systemEvent = ((SimConnectSystemEvent)data.uEventID);
|
||||
var tuple = new Tuple<SimConnectSystemEvent, uint>(systemEvent, data.uEventID);
|
||||
|
||||
// Only look at VIEW for cockpit view during loading of flight (dwData = 2)
|
||||
if (systemEvent == SimConnectSystemEvent.VIEW && data.dwData != 2)
|
||||
return;
|
||||
|
||||
OnReceiveSystemEvent?.Invoke(this, new EventArgs<SimConnectSystemEvent>(systemEvent));
|
||||
OnReceiveSystemEvent?.Invoke(this, new EventArgs<Tuple<SimConnectSystemEvent, uint>>(tuple));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,10 +24,12 @@ namespace MSFSPopoutPanelManager.Model
|
|||
MinimizeToTray = false;
|
||||
AlwaysOnTop = true;
|
||||
UseAutoPanning = true;
|
||||
AutoPanningKeyBinding = "0";
|
||||
StartMinimized = false;
|
||||
IncludeBuiltInPanel = false;
|
||||
AutoPopOutPanels = false;
|
||||
AutoPopOutPanelsWaitDelay = new AutoPopOutPanelsWaitDelay();
|
||||
|
||||
}
|
||||
|
||||
public void Load()
|
||||
|
@ -36,10 +38,12 @@ namespace MSFSPopoutPanelManager.Model
|
|||
this.MinimizeToTray = appSetting.MinimizeToTray;
|
||||
this.AlwaysOnTop = appSetting.AlwaysOnTop;
|
||||
this.UseAutoPanning = appSetting.UseAutoPanning;
|
||||
this.AutoPanningKeyBinding = appSetting.AutoPanningKeyBinding;
|
||||
this.StartMinimized = appSetting.StartMinimized;
|
||||
this.IncludeBuiltInPanel = appSetting.IncludeBuiltInPanel;
|
||||
this.AutoPopOutPanels = appSetting.AutoPopOutPanels;
|
||||
this.AutoPopOutPanelsWaitDelay = appSetting.AutoPopOutPanelsWaitDelay;
|
||||
AutoPopOutPanelsWaitDelay.DataChanged += (e, source) => WriteAppSetting(this);
|
||||
|
||||
_saveEnabled = true;
|
||||
}
|
||||
|
@ -61,19 +65,14 @@ namespace MSFSPopoutPanelManager.Model
|
|||
}
|
||||
}
|
||||
|
||||
//[OnDeserialized]
|
||||
//private void OnDeserialized(StreamingContext context)
|
||||
//{
|
||||
// // Allow save data
|
||||
// _saveEnabled = true;
|
||||
//}
|
||||
|
||||
public bool MinimizeToTray { get; set; }
|
||||
|
||||
public bool AlwaysOnTop { get; set; }
|
||||
|
||||
public bool UseAutoPanning { get; set; }
|
||||
|
||||
public string AutoPanningKeyBinding { get; set; }
|
||||
|
||||
public bool StartMinimized { get; set; }
|
||||
|
||||
public bool IncludeBuiltInPanel { get; set; }
|
||||
|
@ -130,18 +129,23 @@ namespace MSFSPopoutPanelManager.Model
|
|||
serializer.Serialize(file, appSetting);
|
||||
}
|
||||
}
|
||||
catch
|
||||
catch(Exception ex)
|
||||
{
|
||||
Logger.LogStatus($"Unable to write app setting data file: {APP_SETTING_DATA_FILENAME}", StatusMessageType.Error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class AutoPopOutPanelsWaitDelay
|
||||
public class AutoPopOutPanelsWaitDelay : INotifyPropertyChanged
|
||||
{
|
||||
// Using PropertyChanged.Fody
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
public event EventHandler DataChanged;
|
||||
|
||||
public AutoPopOutPanelsWaitDelay()
|
||||
{
|
||||
ReadyToFlyButton = 4;
|
||||
ReadyToFlyButton = 6;
|
||||
InitialCockpitView = 2;
|
||||
InstrumentationPowerOn = 2;
|
||||
}
|
||||
|
@ -151,5 +155,10 @@ namespace MSFSPopoutPanelManager.Model
|
|||
public int InitialCockpitView { get; set; }
|
||||
|
||||
public int InstrumentationPowerOn { get; set; }
|
||||
|
||||
public void OnPropertyChanged(string propertyName, object before, object after)
|
||||
{
|
||||
DataChanged?.Invoke(this, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<RootNamespace>MSFSPopoutPanelManager.Model</RootNamespace>
|
||||
<AssemblyName>Model</AssemblyName>
|
||||
<PackageId>MSFS 2020 Popout Panel Manager Model</PackageId>
|
||||
<Version>3.2.0</Version>
|
||||
<Version>3.3.0.0</Version>
|
||||
<Authors>Stanley Kwok</Authors>
|
||||
<Company>Stanley Kwok</Company>
|
||||
<Copyright>Stanley Kwok 2021</Copyright>
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
|
||||
|
@ -12,6 +14,7 @@ namespace MSFSPopoutPanelManager.Model
|
|||
{
|
||||
PanelSourceCoordinates = new ObservableCollection<PanelSourceCoordinate>();
|
||||
PanelConfigs = new ObservableCollection<PanelConfig>();
|
||||
BindingPlaneTitle = new ObservableCollection<string>();
|
||||
IsLocked = false;
|
||||
}
|
||||
|
||||
|
@ -21,7 +24,8 @@ namespace MSFSPopoutPanelManager.Model
|
|||
|
||||
public bool IsDefaultProfile { get; set; }
|
||||
|
||||
public string BindingPlaneTitle { get; set; }
|
||||
[JsonConverter(typeof(SingleValueArrayConvertor<string>))]
|
||||
public ObservableCollection<string> BindingPlaneTitle { get; set; }
|
||||
|
||||
public bool IsLocked { get; set; }
|
||||
|
||||
|
@ -44,7 +48,41 @@ namespace MSFSPopoutPanelManager.Model
|
|||
[JsonIgnore]
|
||||
public bool HasBindingPlaneTitle
|
||||
{
|
||||
get { return !string.IsNullOrEmpty(BindingPlaneTitle); }
|
||||
get { return BindingPlaneTitle.Count > 0; }
|
||||
}
|
||||
}
|
||||
|
||||
public class SingleValueArrayConvertor<T> : JsonConverter
|
||||
{
|
||||
public override bool CanConvert(Type objectType)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
|
||||
{
|
||||
object val = new object();
|
||||
|
||||
if(reader.TokenType == JsonToken.String)
|
||||
{
|
||||
var instance = (string)serializer.Deserialize(reader, typeof(string));
|
||||
val = new ObservableCollection<string>() { instance };
|
||||
}
|
||||
else if(reader.TokenType == JsonToken.StartArray)
|
||||
{
|
||||
val = serializer.Deserialize(reader, objectType);
|
||||
}
|
||||
else if(reader.TokenType == JsonToken.Null)
|
||||
{
|
||||
val = new ObservableCollection<string>();
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
|
||||
{
|
||||
serializer.Serialize(writer, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -60,8 +60,10 @@ namespace MSFSPopoutPanelManager.Provider
|
|||
Thread.Sleep(200);
|
||||
}
|
||||
|
||||
public static void SaveCustomViewZero(IntPtr hwnd)
|
||||
public static void SaveCustomView(IntPtr hwnd, string keybinding)
|
||||
{
|
||||
uint customViewKey = (uint) (Convert.ToInt32(keybinding) + KEY_0);
|
||||
|
||||
PInvoke.SetForegroundWindow(hwnd);
|
||||
Thread.Sleep(500);
|
||||
|
||||
|
@ -71,15 +73,17 @@ namespace MSFSPopoutPanelManager.Provider
|
|||
// Set view using Ctrl-Alt-0
|
||||
PInvoke.keybd_event(Convert.ToByte(VK_LCONTROL), 0, KEYEVENTF_KEYDOWN, 0);
|
||||
PInvoke.keybd_event(Convert.ToByte(VK_LMENU), 0, KEYEVENTF_KEYDOWN, 0);
|
||||
PInvoke.keybd_event(Convert.ToByte(KEY_0), 0, KEYEVENTF_KEYDOWN, 0);
|
||||
PInvoke.keybd_event(Convert.ToByte(customViewKey), 0, KEYEVENTF_KEYDOWN, 0);
|
||||
Thread.Sleep(200);
|
||||
PInvoke.keybd_event(Convert.ToByte(KEY_0), 0, KEYEVENTF_KEYUP, 0);
|
||||
PInvoke.keybd_event(Convert.ToByte(customViewKey), 0, KEYEVENTF_KEYUP, 0);
|
||||
PInvoke.keybd_event(Convert.ToByte(VK_LMENU), 0, KEYEVENTF_KEYUP, 0);
|
||||
PInvoke.keybd_event(Convert.ToByte(VK_LCONTROL), 0, KEYEVENTF_KEYUP, 0);
|
||||
}
|
||||
|
||||
public static void LoadCustomViewZero(IntPtr hwnd)
|
||||
public static void LoadCustomView(IntPtr hwnd, string keybinding)
|
||||
{
|
||||
uint customViewKey = (uint)(Convert.ToInt32(keybinding) + KEY_0);
|
||||
|
||||
PInvoke.SetForegroundWindow(hwnd);
|
||||
Thread.Sleep(500);
|
||||
|
||||
|
@ -96,9 +100,9 @@ namespace MSFSPopoutPanelManager.Provider
|
|||
|
||||
// Then load view using Alt-0
|
||||
PInvoke.keybd_event(Convert.ToByte(VK_LMENU), 0, KEYEVENTF_KEYDOWN, 0);
|
||||
PInvoke.keybd_event(Convert.ToByte(KEY_0), 0, KEYEVENTF_KEYDOWN, 0);
|
||||
PInvoke.keybd_event(Convert.ToByte(customViewKey), 0, KEYEVENTF_KEYDOWN, 0);
|
||||
Thread.Sleep(200);
|
||||
PInvoke.keybd_event(Convert.ToByte(KEY_0), 0, KEYEVENTF_KEYUP, 0);
|
||||
PInvoke.keybd_event(Convert.ToByte(customViewKey), 0, KEYEVENTF_KEYUP, 0);
|
||||
PInvoke.keybd_event(Convert.ToByte(VK_LMENU), 0, KEYEVENTF_KEYUP, 0);
|
||||
}
|
||||
|
||||
|
|
|
@ -21,13 +21,20 @@ namespace MSFSPopoutPanelManager.Provider
|
|||
|
||||
public const int SWP_NOMOVE = 0x0002;
|
||||
public const int SWP_NOSIZE = 0x0001;
|
||||
public const int SWP_FRAMECHANGED = 0x0020;
|
||||
public const int SWP_NOREDRAW = 0x0008;
|
||||
public const int SWP_ASYNCWINDOWPOS = 0x4000;
|
||||
public const int SWP_ALWAYS_ON_TOP = SWP_NOMOVE | SWP_NOSIZE;
|
||||
|
||||
public const int GWL_STYLE = -16;
|
||||
public const int WS_SIZEBOX = 0x00040000;
|
||||
public const int WS_BORDER = 0x00800000;
|
||||
public const int WS_DLGFRAME = 0x00400000;
|
||||
public const int WS_CAPTION = WS_BORDER | WS_DLGFRAME;
|
||||
public const int GWL_EXSTYLE = -20;
|
||||
public const uint WS_SIZEBOX = 0x00040000;
|
||||
public const uint WS_BORDER = 0x00800000;
|
||||
public const uint WS_DLGFRAME = 0x00400000;
|
||||
public const uint WS_CAPTION = WS_BORDER | WS_DLGFRAME;
|
||||
public const uint WS_POPUP = 0x80000000;
|
||||
public const uint WS_EX_DLGMODALFRAME = 0x00000001;
|
||||
public const uint WS_THICKFRAME = 0x00040000;
|
||||
|
||||
public const int HWND_TOPMOST = -1;
|
||||
public const int HWND_NOTOPMOST = -2;
|
||||
|
|
|
@ -61,21 +61,20 @@ namespace MSFSPopoutPanelManager.Provider
|
|||
break;
|
||||
case PanelConfigPropertyName.Left:
|
||||
case PanelConfigPropertyName.Top:
|
||||
// Do not allow changes to panel if title bar is hidden. This will cause the panel to resize incorrectly
|
||||
if (panelConfig.HideTitlebar)
|
||||
return;
|
||||
|
||||
PInvoke.MoveWindow(panelConfig.PanelHandle, panelConfig.Left, panelConfig.Top, panelConfig.Width, panelConfig.Height, true);
|
||||
break;
|
||||
case PanelConfigPropertyName.Width:
|
||||
case PanelConfigPropertyName.Height:
|
||||
// Do not allow changes to panel if title bar is hidden. This will cause the panel to resize incorrectly
|
||||
if (panelConfig.HideTitlebar)
|
||||
return;
|
||||
WindowManager.ApplyHidePanelTitleBar(panelConfig.PanelHandle, false);
|
||||
|
||||
int orignalLeft = panelConfig.Left;
|
||||
PInvoke.MoveWindow(panelConfig.PanelHandle, panelConfig.Left, panelConfig.Top, panelConfig.Width, panelConfig.Height, true);
|
||||
MSFSBugPanelShiftWorkaround(panelConfig.PanelHandle, orignalLeft, panelConfig.Top, panelConfig.Width, panelConfig.Height);
|
||||
|
||||
if (panelConfig.HideTitlebar)
|
||||
WindowManager.ApplyHidePanelTitleBar(panelConfig.PanelHandle, true);
|
||||
|
||||
break;
|
||||
case PanelConfigPropertyName.AlwaysOnTop:
|
||||
WindowManager.ApplyAlwaysOnTop(panelConfig.PanelHandle, panelConfig.AlwaysOnTop, new Rectangle(panelConfig.Left, panelConfig.Top, panelConfig.Width, panelConfig.Height));
|
||||
|
@ -99,32 +98,43 @@ namespace MSFSPopoutPanelManager.Provider
|
|||
if (index > -1)
|
||||
{
|
||||
var panelConfig = UserProfile.PanelConfigs[index];
|
||||
|
||||
// Do not allow changes to panel if title bar is hidden. This will cause the panel to resize incorrectly
|
||||
if (panelConfig.HideTitlebar)
|
||||
return;
|
||||
|
||||
int orignalLeft = panelConfig.Left;
|
||||
|
||||
switch (panelConfigItem.PanelConfigProperty)
|
||||
{
|
||||
case PanelConfigPropertyName.Left:
|
||||
PInvoke.MoveWindow(panelConfig.PanelHandle, panelConfig.Left + changeAmount, panelConfig.Top, panelConfig.Width, panelConfig.Height, false);
|
||||
panelConfig.Left += changeAmount;
|
||||
PInvoke.MoveWindow(panelConfig.PanelHandle, panelConfig.Left, panelConfig.Top, panelConfig.Width, panelConfig.Height, false);
|
||||
break;
|
||||
case PanelConfigPropertyName.Top:
|
||||
PInvoke.MoveWindow(panelConfig.PanelHandle, panelConfig.Left, panelConfig.Top + changeAmount, panelConfig.Width, panelConfig.Height, false);
|
||||
panelConfig.Top += changeAmount;
|
||||
PInvoke.MoveWindow(panelConfig.PanelHandle, panelConfig.Left, panelConfig.Top, panelConfig.Width, panelConfig.Height, false);
|
||||
break;
|
||||
case PanelConfigPropertyName.Width:
|
||||
PInvoke.MoveWindow(panelConfig.PanelHandle, panelConfig.Left, panelConfig.Top, panelConfig.Width + changeAmount, panelConfig.Height, false);
|
||||
MSFSBugPanelShiftWorkaround(panelConfig.PanelHandle, orignalLeft, panelConfig.Top, panelConfig.Width + changeAmount, panelConfig.Height);
|
||||
panelConfig.Width += changeAmount;
|
||||
|
||||
if (panelConfig.HideTitlebar)
|
||||
WindowManager.ApplyHidePanelTitleBar(panelConfig.PanelHandle, false);
|
||||
|
||||
PInvoke.MoveWindow(panelConfig.PanelHandle, panelConfig.Left, panelConfig.Top, panelConfig.Width, panelConfig.Height, false);
|
||||
MSFSBugPanelShiftWorkaround(panelConfig.PanelHandle, orignalLeft, panelConfig.Top, panelConfig.Width, panelConfig.Height);
|
||||
|
||||
if (panelConfig.HideTitlebar)
|
||||
WindowManager.ApplyHidePanelTitleBar(panelConfig.PanelHandle, true);
|
||||
|
||||
break;
|
||||
case PanelConfigPropertyName.Height:
|
||||
PInvoke.MoveWindow(panelConfig.PanelHandle, panelConfig.Left, panelConfig.Top, panelConfig.Width, panelConfig.Height + changeAmount, false);
|
||||
MSFSBugPanelShiftWorkaround(panelConfig.PanelHandle, orignalLeft, panelConfig.Top, panelConfig.Width, panelConfig.Height + changeAmount);
|
||||
panelConfig.Height += changeAmount;
|
||||
|
||||
if (panelConfig.HideTitlebar)
|
||||
WindowManager.ApplyHidePanelTitleBar(panelConfig.PanelHandle, false);
|
||||
|
||||
PInvoke.MoveWindow(panelConfig.PanelHandle, panelConfig.Left, panelConfig.Top, panelConfig.Width, panelConfig.Height, false);
|
||||
MSFSBugPanelShiftWorkaround(panelConfig.PanelHandle, orignalLeft, panelConfig.Top, panelConfig.Width, panelConfig.Height);
|
||||
|
||||
if (panelConfig.HideTitlebar)
|
||||
WindowManager.ApplyHidePanelTitleBar(panelConfig.PanelHandle, true);
|
||||
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
|
@ -211,8 +221,17 @@ namespace MSFSPopoutPanelManager.Provider
|
|||
|
||||
panelConfig.Left = winRectangle.Left;
|
||||
panelConfig.Top = winRectangle.Top;
|
||||
|
||||
if (panelConfig.HideTitlebar)
|
||||
{
|
||||
panelConfig.Width = clientRectangle.Width;
|
||||
panelConfig.Height = clientRectangle.Height;
|
||||
}
|
||||
else
|
||||
{
|
||||
panelConfig.Width = clientRectangle.Width + 16;
|
||||
panelConfig.Height = clientRectangle.Height + 39;
|
||||
}
|
||||
|
||||
// Detect if window is maximized, if so, save settings
|
||||
WINDOWPLACEMENT wp = new WINDOWPLACEMENT();
|
||||
|
|
|
@ -52,7 +52,7 @@ namespace MSFSPopoutPanelManager.Provider
|
|||
var simualatorProcess = DiagnosticManager.GetSimulatorProcess();
|
||||
if (simualatorProcess != null)
|
||||
{
|
||||
InputEmulationManager.LoadCustomViewZero(simualatorProcess.Handle);
|
||||
InputEmulationManager.LoadCustomView(simualatorProcess.Handle, AppSetting.AutoPanningKeyBinding);
|
||||
Thread.Sleep(500);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -86,7 +86,7 @@ namespace MSFSPopoutPanelManager.Provider
|
|||
var simualatorProcess = DiagnosticManager.GetSimulatorProcess();
|
||||
if (simualatorProcess != null)
|
||||
{
|
||||
InputEmulationManager.SaveCustomViewZero(simualatorProcess.Handle);
|
||||
InputEmulationManager.SaveCustomView(simualatorProcess.Handle, AppSetting.AutoPanningKeyBinding);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<RootNamespace>MSFSPopoutPanelManager.Provider</RootNamespace>
|
||||
<PackageId>MSFS 2020 Popout Panel Manager Provider</PackageId>
|
||||
<Product>MSFS 2020 Popout Panel Manager Provider</Product>
|
||||
<Version>3.2.0</Version>
|
||||
<Version>3.3.0.0</Version>
|
||||
<Authors>Stanley Kwok</Authors>
|
||||
<Copyright>Stanley Kwok 2021</Copyright>
|
||||
<PackageProjectUrl>https://github.com/hawkeye-stan/msfs-popout-panel-manager</PackageProjectUrl>
|
||||
|
|
|
@ -17,6 +17,7 @@ namespace MSFSPopoutPanelManager.Provider
|
|||
|
||||
private System.Timers.Timer _requestDataTimer;
|
||||
private SimConnectSystemEvent _lastSystemEvent;
|
||||
private bool _isSimActive;
|
||||
private bool _isPowerOnForPopOut;
|
||||
|
||||
public event EventHandler OnConnected;
|
||||
|
@ -43,16 +44,19 @@ namespace MSFSPopoutPanelManager.Provider
|
|||
_requestDataTimer.Elapsed += HandleMessageReceived;
|
||||
};
|
||||
|
||||
_isSimActive = false;
|
||||
_simConnector.Start();
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
_isSimActive = false;
|
||||
_simConnector.Stop();
|
||||
}
|
||||
|
||||
public void Restart()
|
||||
{
|
||||
_isSimActive = false;
|
||||
_simConnector.StopAndReconnect();
|
||||
}
|
||||
|
||||
|
@ -115,17 +119,32 @@ namespace MSFSPopoutPanelManager.Provider
|
|||
OnSimConnectDataRefreshed?.Invoke(this, new EventArgs<dynamic>(e.Value));
|
||||
}
|
||||
|
||||
private void HandleReceiveSystemEvent(object sender, EventArgs<SimConnectSystemEvent> e)
|
||||
private void HandleReceiveSystemEvent(object sender, EventArgs<Tuple<SimConnectSystemEvent, uint>> e)
|
||||
{
|
||||
var systemEvent = e.Value.Item1;
|
||||
var dwData = e.Value.Item2;
|
||||
|
||||
Debug.WriteLine($"SimConnectSystemEvent Received: {systemEvent} dwData: {dwData}");
|
||||
|
||||
// to detect flight start at the "Ready to Fly" screen, it has a SIMSTART follows by a VIEW event
|
||||
if(_lastSystemEvent == SimConnectSystemEvent.SIMSTART && e.Value == SimConnectSystemEvent.VIEW)
|
||||
if (_lastSystemEvent == SimConnectSystemEvent.SIMSTART && systemEvent == SimConnectSystemEvent.VIEW && dwData == 4)
|
||||
{
|
||||
_isSimActive = true;
|
||||
OnFlightStarted?.Invoke(this, null);
|
||||
return;
|
||||
}
|
||||
|
||||
if (e.Value == SimConnectSystemEvent.SIMSTOP)
|
||||
// look for pair of events denoting sim ended after sim is active
|
||||
if ((_isSimActive && _lastSystemEvent == SimConnectSystemEvent.SIMSTOP && systemEvent == SimConnectSystemEvent.VIEW && dwData == 4) ||
|
||||
(_isSimActive && _lastSystemEvent == SimConnectSystemEvent.SIMSTOP && systemEvent == SimConnectSystemEvent.SIMSTART && dwData == 1))
|
||||
{
|
||||
_isSimActive = false;
|
||||
_lastSystemEvent = SimConnectSystemEvent.NONE;
|
||||
OnFlightStopped?.Invoke(this, null);
|
||||
return;
|
||||
}
|
||||
|
||||
Debug.WriteLine($"SimConnectSystemEvent Received: {e.Value.ToString()}");
|
||||
_lastSystemEvent = e.Value;
|
||||
_lastSystemEvent = systemEvent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ namespace MSFSPopoutPanelManager.Provider
|
|||
|
||||
var copiedProfile = matchedProfile.Copy<UserProfile>(); // Using Shared/ObjectExtensions.cs extension method
|
||||
copiedProfile.IsDefaultProfile = false;
|
||||
copiedProfile.BindingPlaneTitle = null;
|
||||
copiedProfile.BindingPlaneTitle = new ObservableCollection<string>();
|
||||
|
||||
return AddProfile(copiedProfile, newProfileName);
|
||||
}
|
||||
|
@ -83,21 +83,22 @@ namespace MSFSPopoutPanelManager.Provider
|
|||
|
||||
public void AddProfileBinding(string planeTitle, int activeProfileId)
|
||||
{
|
||||
var bindedProfile = UserProfiles.FirstOrDefault(p => p.BindingPlaneTitle == planeTitle);
|
||||
var bindedProfile = UserProfiles.FirstOrDefault(p => p.BindingPlaneTitle.ToList().Exists(p => p == planeTitle));
|
||||
if (bindedProfile != null)
|
||||
{
|
||||
Logger.LogStatus($"Unable to add binding to the profile because '{planeTitle}' was already bound to profile '{bindedProfile.ProfileName}'.", StatusMessageType.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
UserProfiles.First(p => p.ProfileId == activeProfileId).BindingPlaneTitle = planeTitle;
|
||||
UserProfiles.First(p => p.ProfileId == activeProfileId).BindingPlaneTitle.Add(planeTitle);
|
||||
WriteUserProfiles();
|
||||
|
||||
Logger.LogStatus($"Binding for the profile has been added successfully.", StatusMessageType.Info);
|
||||
}
|
||||
|
||||
public void DeleteProfileBinding(int activeProfileId)
|
||||
public void DeleteProfileBinding(string planeTitle, int activeProfileId)
|
||||
{
|
||||
UserProfiles.First(p => p.ProfileId == activeProfileId).BindingPlaneTitle = null;
|
||||
UserProfiles.First(p => p.ProfileId == activeProfileId).BindingPlaneTitle.Remove(planeTitle);
|
||||
WriteUserProfiles();
|
||||
Logger.LogStatus($"Binding for the profile has been deleted successfully.", StatusMessageType.Info);
|
||||
}
|
||||
|
@ -111,7 +112,7 @@ namespace MSFSPopoutPanelManager.Provider
|
|||
UserProfiles = new ObservableCollection<UserProfile>(JsonConvert.DeserializeObject<List<UserProfile>>(reader.ReadToEnd()));
|
||||
}
|
||||
}
|
||||
catch
|
||||
catch(Exception ex)
|
||||
{
|
||||
UserProfiles = new ObservableCollection<UserProfile>(new List<UserProfile>());
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
using MSFSPopoutPanelManager.Shared;
|
||||
using System;
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
|
@ -45,7 +44,7 @@ namespace MSFSPopoutPanelManager.Provider
|
|||
{
|
||||
Rectangle rectangle;
|
||||
PInvoke.GetClientRect(handle, out rectangle);
|
||||
PInvoke.MoveWindow(handle, x, y, rectangle.Width, rectangle.Height, false);
|
||||
PInvoke.MoveWindow(handle, x, y, rectangle.Width, rectangle.Height, true);
|
||||
}
|
||||
|
||||
public static void MinimizeWindow(IntPtr handle)
|
||||
|
|
|
@ -154,6 +154,8 @@ The user plane profile data and application settings data are stored as JSON fil
|
|||
|
||||
* If you encounter application crashes or unknown error, please help my continuing development effort by attaching the file **error.log** in the application folder and open an issue ticket in github repo for this project. This is going to help me troubleshoot the issue and provide hotfixes.
|
||||
|
||||
* If you encounter an issue with panels that are not restored back to your saved profile locations, please check if you have other apps such as Sizer or Windows PowerToys that may have conflict with Pop Out Manager.
|
||||
|
||||
|
||||
## Author
|
||||
Stanley Kwok
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
<Company>Stanley Kwok</Company>
|
||||
<Copyright>Stanley Kwok 2021</Copyright>
|
||||
<PackageProjectUrl>https://github.com/hawkeye-stan/msfs-popout-panel-manager</PackageProjectUrl>
|
||||
<Version>3.2.0</Version>
|
||||
<Version>3.3.0.0</Version>
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
<UseWPF>true</UseWPF>
|
||||
</PropertyGroup>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<hr/>
|
||||
|
||||
|
||||
## Version 3.2.0 (Release)
|
||||
## Version 3.2.0.1 (v3.2 Release)
|
||||
* Added application auto update support. By installing this version of the app, auto update functionality will be available for all future versions of the application.
|
||||
* Disabled panel adjustments when Hide Title Bar is checked for a panel. This is to fix an issue where panel adjustments (X-Pos, Y-Pos, Width, and Height) will behave erratically when Hide Title Bar is checked.
|
||||
* Increased default delay for auto-clicking "Ready to Fly" button from 2 seconds to 4 seconds in regard to Auto Pop Out Panels feature . [Fixed Issue #9](https://github.com/hawkeye-stan/msfs-popout-panel-manager/issues/9)
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls"
|
||||
xmlns:mah="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
|
||||
xmlns:local="clr-namespace:MSFSPopoutPanelManager.WpfApp"
|
||||
StartupUri="ApplicationWindow.xaml">
|
||||
<Application.Resources>
|
||||
|
|
|
@ -124,7 +124,7 @@ namespace MSFSPopoutPanelManager.WpfApp
|
|||
var process = DiagnosticManager.GetApplicationProcess();
|
||||
PROCESS_DPI_AWARENESS outValue;
|
||||
GetProcessDpiAwareness(process.Handle, out outValue);
|
||||
log4net.Info($"DPI Awareness is set to: {outValue}");
|
||||
//log4net.Info($"DPI Awareness is set to: {outValue}");
|
||||
}
|
||||
|
||||
[DllImport("User32.dll")]
|
||||
|
|
|
@ -53,15 +53,7 @@
|
|||
<MenuItem Header="File">
|
||||
<MenuItem Name="menuItem_Restart" Header="Restart" Command="{Binding Path=RestartCommand}" IsEnabled="{Binding Path=IsShownPanelConfigurationScreen}"/>
|
||||
<Separator />
|
||||
<MenuItem Header="Preferences">
|
||||
<MenuItem Name="menuItem_AlwaysOnTop" Header="Always on Top" IsChecked="{Binding Path=DataStore.AppSetting.AlwaysOnTop, Mode=TwoWay}" IsCheckable="True"/>
|
||||
<MenuItem Name="menuItem_AutoPanning" Header="Auto Panning" IsChecked="{Binding Path=DataStore.AppSetting.UseAutoPanning, Mode=TwoWay}" IsCheckable="True"/>
|
||||
<MenuItem Name="menuItem_AutoPopOutPanels" Header="Auto Pop Out Panels" IsChecked="{Binding Path=DataStore.AppSetting.AutoPopOutPanels, Mode=TwoWay}" IsCheckable="True"/>
|
||||
<MenuItem Name="menuItem_AutoStart" Header="Auto Start" IsChecked="{Binding Path=DataStore.AppSetting.AutoStart, Mode=TwoWay}" IsCheckable="True"/>
|
||||
<MenuItem Name="menuItem_IncludeBuiltInPanel" Header="Include Built-in Panels" IsChecked="{Binding Path=DataStore.AppSetting.IncludeBuiltInPanel, Mode=TwoWay}" IsCheckable="True"/>
|
||||
<MenuItem Name="menuItem_MinimizeToTray" Header="Minimize to Tray" IsChecked="{Binding Path=DataStore.AppSetting.MinimizeToTray, Mode=TwoWay}" IsCheckable="True"/>
|
||||
<MenuItem Name="menuItem_StartMinimized" Header="Start Minimized" IsChecked="{Binding Path=DataStore.AppSetting.StartMinimized, Mode=TwoWay}" IsCheckable="True"/>
|
||||
</MenuItem>
|
||||
<MenuItem Header="Preferences" Click="EditPreferences_Click" />
|
||||
<Separator />
|
||||
<MenuItem Name="menuItem_Exit" Header="Exit" Command="{Binding Path=ExitCommand}"/>
|
||||
</MenuItem>
|
||||
|
|
|
@ -99,5 +99,15 @@ namespace MSFSPopoutPanelManager.WpfApp
|
|||
{
|
||||
_viewModel.ExitCommand.Execute(null);
|
||||
}
|
||||
|
||||
private void EditPreferences_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
PreferencesDialog dialog = new PreferencesDialog(_viewModel.DataStore.AppSetting);
|
||||
dialog.Owner = Application.Current.MainWindow;
|
||||
dialog.Topmost = true;
|
||||
dialog.WindowStartupLocation = WindowStartupLocation.CenterOwner;
|
||||
|
||||
dialog.ShowDialog();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,7 +31,15 @@ namespace MSFSPopoutPanelManager.WpfApp
|
|||
|
||||
this.Loaded += (sender, e) =>
|
||||
{
|
||||
var dialogHandle = new WindowInteropHelper(Window.GetWindow(this)).Handle;
|
||||
var winObj = Window.GetWindow(this);
|
||||
|
||||
if (winObj != null)
|
||||
{
|
||||
var window = new WindowInteropHelper(winObj);
|
||||
|
||||
if (window != null)
|
||||
{
|
||||
var dialogHandle = window.Handle;
|
||||
var simulatorProcessHandle = DiagnosticManager.GetSimulatorProcess().Handle;
|
||||
|
||||
Rectangle rectangle;
|
||||
|
@ -47,6 +55,8 @@ namespace MSFSPopoutPanelManager.WpfApp
|
|||
Debug.WriteLine($"Message Dialog Location: X:{x} Y:{y}");
|
||||
|
||||
PInvoke.MoveWindow(dialogHandle, x, y, Convert.ToInt32(this.Width), Convert.ToInt32(this.Height), false);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
System.Timers.Timer timer = new System.Timers.Timer();
|
||||
|
|
101
WpfApp/PreferencesDialog.xaml
Normal file
101
WpfApp/PreferencesDialog.xaml
Normal file
|
@ -0,0 +1,101 @@
|
|||
<mah:MetroWindow x:Class="MSFSPopoutPanelManager.WpfApp.PreferencesDialog"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:mah="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
|
||||
xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase"
|
||||
xmlns:c="clr-namespace:CalcBinding;assembly=CalcBinding"
|
||||
xmlns:local="clr-namespace:MSFSPopoutPanelManager.WpfApp"
|
||||
mc:Ignorable="d"
|
||||
Title="Preferences"
|
||||
Height="450"
|
||||
Width="800"
|
||||
ResizeMode="NoResize"
|
||||
Background="Transparent">
|
||||
<Grid>
|
||||
<DockPanel>
|
||||
<TreeView Width="250" VerticalAlignment="Stretch" DockPanel.Dock="Left">
|
||||
<TreeView.ItemContainerStyle>
|
||||
<Style TargetType="{x:Type TreeViewItem}">
|
||||
<Setter Property="IsExpanded" Value="True" />
|
||||
<Setter Property="Foreground" Value="#666666" />
|
||||
<Setter Property="Background" Value="Transparent" />
|
||||
<Style.Resources>
|
||||
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Transparent"/>
|
||||
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightTextBrushKey}" Color="White"/>
|
||||
<SolidColorBrush x:Key="{x:Static SystemColors.InactiveSelectionHighlightBrushKey }" Color="Transparent"/>
|
||||
<SolidColorBrush x:Key="{x:Static SystemColors.InactiveSelectionHighlightTextBrushKey }" Color="White"/>
|
||||
|
||||
</Style.Resources>
|
||||
</Style>
|
||||
</TreeView.ItemContainerStyle>
|
||||
<TreeViewItem Header="Application Settings" Selected="TreeViewItem_Selected" Margin="0,15,0,10" IsSelected="True"></TreeViewItem>
|
||||
<TreeViewItem Header="Pop Out Settings" Selected="TreeViewItem_Selected" Margin="0,0,0,10"></TreeViewItem>
|
||||
<TreeViewItem Header="Auto Pop Out Settings" Selected="TreeViewItem_Selected" Margin="0,0,0,10"></TreeViewItem>
|
||||
</TreeView>
|
||||
<WrapPanel Orientation="Vertical" DockPanel.Dock="Right" Margin="20,5,0,0" >
|
||||
<WrapPanel Orientation="Vertical" Margin="0,10,0,0" Width="500" Visibility="{Binding Path=ApplicationSettingsVisibility, Mode=TwoWay}">
|
||||
<CheckBox Margin="0,0,0,0" IsChecked="{Binding Path=AppSetting.AlwaysOnTop, Mode=TwoWay}" Content="Always on Top"></CheckBox>
|
||||
<TextBlock Margin="24,5,0,10" Width="Auto" TextWrapping="Wrap" FontSize="14">Pin the application on top of all open windows.</TextBlock>
|
||||
<CheckBox Margin="0,0,0,0" IsChecked="{Binding Path=AppSetting.AutoStart, Mode=TwoWay}" Content="Auto Start"></CheckBox>
|
||||
<TextBlock Margin="24,5,0,10" Width="Auto" TextWrapping="Wrap" FontSize="14">Auto start the application when MSFS starts. This adds a XML config entry in EXE.xml file.</TextBlock>
|
||||
<CheckBox IsChecked="{Binding Path=AppSetting.MinimizeToTray, Mode=TwoWay}" Content="Minimize to Tray"></CheckBox>
|
||||
<TextBlock Margin="24,5,0,10" Width="Auto" TextWrapping="Wrap" FontSize="14">Minimize the application to system tray.</TextBlock>
|
||||
<CheckBox IsChecked="{Binding Path=AppSetting.StartMinimized, Mode=TwoWay}" Content="Start Minimized"></CheckBox>
|
||||
<TextBlock Margin="24,5,0,10" Width="Auto" TextWrapping="Wrap" FontSize="14">Start the application in minimized mode in system tray.</TextBlock>
|
||||
</WrapPanel>
|
||||
<WrapPanel Orientation="Vertical" Margin="0,10,0,0" Visibility="{Binding Path=PopOutSettingsVisibility, Mode=TwoWay}">
|
||||
<CheckBox IsChecked="{Binding Path=AppSetting.UseAutoPanning, Mode=TwoWay}" Content="Auto Panning"></CheckBox>
|
||||
<TextBlock Margin="24,5,0,10" Width="Auto" TextWrapping="Wrap" FontSize="14">Enable automatic panning of cockpit view when popping out panels. Auto Panning remembers the custom cockpit camera angle you used when defining the locations of pop out panel.</TextBlock>
|
||||
<TextBlock Margin="24,10,0,0" Width="Auto" TextWrapping="Wrap" >Key Binding</TextBlock>
|
||||
<TextBlock Margin="24,5,0,10" Width="Auto" TextWrapping="Wrap" FontSize="14">Configure key binding for saving and recalling of custom MSFS cockpit camera view when defining the locations of pop out panel. Default is Ctrl-Alt-0.</TextBlock>
|
||||
<WrapPanel Orientation="Horizontal" Margin="20,10,0,0">
|
||||
<Label Content="Ctrl-Alt-" FontSize="14"></Label>
|
||||
<ComboBox HorizontalAlignment="Left"
|
||||
VerticalAlignment="Center"
|
||||
Width="60"
|
||||
SelectedValuePath="Tag"
|
||||
SelectedValue="{Binding Path=AppSetting.AutoPanningKeyBinding, Mode=TwoWay}" >
|
||||
<ComboBoxItem Content="0" Tag="0"></ComboBoxItem>
|
||||
<ComboBoxItem Content="1" Tag="1"></ComboBoxItem>
|
||||
<ComboBoxItem Content="2" Tag="2"></ComboBoxItem>
|
||||
<ComboBoxItem Content="3" Tag="3"></ComboBoxItem>
|
||||
<ComboBoxItem Content="4" Tag="4"></ComboBoxItem>
|
||||
<ComboBoxItem Content="5" Tag="5"></ComboBoxItem>
|
||||
<ComboBoxItem Content="6" Tag="6"></ComboBoxItem>
|
||||
<ComboBoxItem Content="7" Tag="7"></ComboBoxItem>
|
||||
<ComboBoxItem Content="8" Tag="8"></ComboBoxItem>
|
||||
<ComboBoxItem Content="9" Tag="9"></ComboBoxItem>
|
||||
</ComboBox>
|
||||
</WrapPanel>
|
||||
<CheckBox Margin="0,15,0,0" IsChecked="{Binding Path=AppSetting.IncludeBuiltInPanel, Mode=TwoWay}" Content="Include Built-in Panels"></CheckBox>
|
||||
<TextBlock Margin="24,5,0,10" Width="Auto" TextWrapping="Wrap" FontSize="14">Enable saving and recalling of MSFS built-in panels (ie. ATC, VFR Map, Checklist, etc) as part of profile definition.</TextBlock>
|
||||
</WrapPanel>
|
||||
<WrapPanel Orientation="Vertical" Margin="0,10,0,0" Visibility="{Binding Path=AutoPopOutSettingsVisibility, Mode=TwoWay}">
|
||||
<CheckBox IsChecked="{Binding Path=AppSetting.AutoPopOutPanels, Mode=TwoWay}" Content="Auto Pop Out Panels"></CheckBox>
|
||||
<TextBlock Margin="24,10,0,10" Width="Auto" TextWrapping="Wrap" >Wait delay for each step during auto pop out process (in seconds)</TextBlock>
|
||||
<WrapPanel Orientation="Horizontal" Margin="24,0,0,0" >
|
||||
<mah:NumericUpDown Width="80" Minimum="1" Maximum="30" FontSize="16" Height="32" Value="{Binding Path=AppSetting.AutoPopOutPanelsWaitDelay.ReadyToFlyButton, Mode=TwoWay}"></mah:NumericUpDown>
|
||||
<Label Margin="10,0,0,0">Ready to Fly</Label>
|
||||
</WrapPanel>
|
||||
<TextBlock Margin="119,0,10,10" Width="Auto" TextWrapping="Wrap" FontSize="14">Amount of time to wait for 'Ready to Fly' button to appear before simulating mouse click.<LineBreak/>(Default: 6 seconds)</TextBlock>
|
||||
<WrapPanel Orientation="Horizontal" Margin="24,0,0,0" >
|
||||
<mah:NumericUpDown Width="80" Minimum="1" Maximum="30" FontSize="16" Height="32" Value="{Binding Path=AppSetting.AutoPopOutPanelsWaitDelay.InitialCockpitView, Mode=TwoWay}"></mah:NumericUpDown>
|
||||
<Label Margin="10,0,0,0" >Initial Cockpit View</Label>
|
||||
</WrapPanel>
|
||||
<TextBlock Margin="119,0,10,10" Width="Auto" TextWrapping="Wrap" FontSize="14">Amount of time to wait for the cockpit to appear before beginning pop out panel process.<LineBreak/>(Default: 2 seconds)</TextBlock>
|
||||
<WrapPanel Orientation="Horizontal" Margin="24,0,0,00" >
|
||||
<mah:NumericUpDown Width="80" Minimum="1" Maximum="30" FontSize="16" Height="32" Value="{Binding Path=AppSetting.AutoPopOutPanelsWaitDelay.InstrumentationPowerOn, Mode=TwoWay}"></mah:NumericUpDown>
|
||||
<Label Margin="10,0,0,0">Instrumentation Power On</Label>
|
||||
</WrapPanel>
|
||||
<TextBlock Margin="119,0,10,10" Width="Auto" TextWrapping="Wrap" FontSize="14">Amount of time to wait for cold start instrumentation power on to complete before beginning pop out panel process.<LineBreak/>(Default: 2 seconds)</TextBlock>
|
||||
<WrapPanel Orientation="Horizontal"></WrapPanel>
|
||||
</WrapPanel>
|
||||
<WrapPanel Orientation="Vertical" Visibility="Visible">
|
||||
</WrapPanel>
|
||||
</WrapPanel>
|
||||
|
||||
</DockPanel>
|
||||
</Grid>
|
||||
</mah:MetroWindow>
|
63
WpfApp/PreferencesDialog.xaml.cs
Normal file
63
WpfApp/PreferencesDialog.xaml.cs
Normal file
|
@ -0,0 +1,63 @@
|
|||
using MahApps.Metro.Controls;
|
||||
using MSFSPopoutPanelManager.Model;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace MSFSPopoutPanelManager.WpfApp
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for AddProfileDialog.xaml
|
||||
/// </summary>
|
||||
public partial class PreferencesDialog : MetroWindow, INotifyPropertyChanged
|
||||
{
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
public PreferencesDialog(AppSetting appSetting)
|
||||
{
|
||||
InitializeComponent();
|
||||
AppSetting = appSetting;
|
||||
|
||||
this.DataContext = this;
|
||||
|
||||
ApplicationSettingsVisibility = Visibility.Visible;
|
||||
PopOutSettingsVisibility = Visibility.Collapsed;
|
||||
AutoPopOutSettingsVisibility = Visibility.Collapsed;
|
||||
}
|
||||
|
||||
public AppSetting AppSetting { get; set; }
|
||||
|
||||
public Visibility ApplicationSettingsVisibility { get; set; }
|
||||
|
||||
public Visibility PopOutSettingsVisibility { get; set; }
|
||||
|
||||
public Visibility AutoPopOutSettingsVisibility { get; set; }
|
||||
|
||||
private void TreeViewItem_Selected(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var treeViewItem = (TreeViewItem)e.Source;
|
||||
|
||||
ApplicationSettingsVisibility = Visibility.Collapsed;
|
||||
PopOutSettingsVisibility = Visibility.Collapsed;
|
||||
AutoPopOutSettingsVisibility = Visibility.Collapsed;
|
||||
|
||||
if (treeViewItem.Header.ToString() == "Application Settings")
|
||||
{
|
||||
ApplicationSettingsVisibility = Visibility.Visible;
|
||||
}
|
||||
else if(treeViewItem.Header.ToString() == "Pop Out Settings")
|
||||
{
|
||||
PopOutSettingsVisibility = Visibility.Visible;
|
||||
}
|
||||
else if (treeViewItem.Header.ToString() == "Auto Pop Out Settings")
|
||||
{
|
||||
AutoPopOutSettingsVisibility = Visibility.Visible;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -121,7 +121,7 @@
|
|||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<TextBox Name="Left" Width="100" BorderThickness="0" Text="{Binding Path=Left, Mode=TwoWay, NotifyOnSourceUpdated=True, UpdateSourceTrigger=LostFocus}"
|
||||
SourceUpdated="GridData_SourceUpdated" Style="{StaticResource TextBoxColumnFocus}" IsReadOnly="{c:Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid, AncestorLevel=1}, Path='DataContext.DataStore.ActiveUserProfile.IsLocked or !DataContext.DataStore.AllowEdit'}" IsEnabled="{c:Binding Path='!HideTitlebar', Mode=TwoWay}" />
|
||||
SourceUpdated="GridData_SourceUpdated" Style="{StaticResource TextBoxColumnFocus}" IsReadOnly="{c:Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid, AncestorLevel=1}, Path='DataContext.DataStore.ActiveUserProfile.IsLocked or !DataContext.DataStore.AllowEdit'}" />
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
|
@ -129,7 +129,7 @@
|
|||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<TextBox Name="Top" Width="100" BorderThickness="0" Text="{Binding Path=Top, Mode=TwoWay, NotifyOnSourceUpdated=True, UpdateSourceTrigger=LostFocus}"
|
||||
SourceUpdated="GridData_SourceUpdated" Style="{StaticResource TextBoxColumnFocus}" IsReadOnly="{c:Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid, AncestorLevel=1}, Path='DataContext.DataStore.ActiveUserProfile.IsLocked or !DataContext.DataStore.AllowEdit'}" IsEnabled="{c:Binding Path='!HideTitlebar', Mode=TwoWay}" />
|
||||
SourceUpdated="GridData_SourceUpdated" Style="{StaticResource TextBoxColumnFocus}" IsReadOnly="{c:Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid, AncestorLevel=1}, Path='DataContext.DataStore.ActiveUserProfile.IsLocked or !DataContext.DataStore.AllowEdit'}" />
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
|
@ -137,7 +137,7 @@
|
|||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<TextBox Name="Width" Width="100" BorderThickness="0" Text="{Binding Path=Width, Mode=TwoWay, NotifyOnSourceUpdated=True, UpdateSourceTrigger=LostFocus}"
|
||||
SourceUpdated="GridData_SourceUpdated" Style="{StaticResource TextBoxColumnFocus}" IsReadOnly="{c:Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid, AncestorLevel=1}, Path='DataContext.DataStore.ActiveUserProfile.IsLocked or !DataContext.DataStore.AllowEdit'}" IsEnabled="{c:Binding Path='!HideTitlebar', Mode=TwoWay}" />
|
||||
SourceUpdated="GridData_SourceUpdated" Style="{StaticResource TextBoxColumnFocus}" IsReadOnly="{c:Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid, AncestorLevel=1}, Path='DataContext.DataStore.ActiveUserProfile.IsLocked or !DataContext.DataStore.AllowEdit'}" />
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
|
@ -145,7 +145,7 @@
|
|||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<TextBox Name="Height" Width="100" BorderThickness="0" Text="{Binding Path=Height, Mode=TwoWay, NotifyOnSourceUpdated=True, UpdateSourceTrigger=LostFocus}"
|
||||
SourceUpdated="GridData_SourceUpdated" Style="{StaticResource TextBoxColumnFocus}" IsReadOnly="{c:Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid, AncestorLevel=1}, Path='DataContext.DataStore.ActiveUserProfile.IsLocked or !DataContext.DataStore.AllowEdit'}" IsEnabled="{c:Binding Path='!HideTitlebar', Mode=TwoWay}" />
|
||||
SourceUpdated="GridData_SourceUpdated" Style="{StaticResource TextBoxColumnFocus}" IsReadOnly="{c:Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid, AncestorLevel=1}, Path='DataContext.DataStore.ActiveUserProfile.IsLocked or !DataContext.DataStore.AllowEdit'}" />
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
|
@ -157,7 +157,7 @@
|
|||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
<DataGridTemplateColumn Header="Hide Titlebar" Width="100">
|
||||
<DataGridTemplateColumn Header="Hide Title Bar" Width="100">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<CheckBox Name="HideTitlebar" Width="100" Margin="40 0 0 0" IsChecked="{Binding Path=HideTitlebar, Mode=TwoWay, NotifyOnSourceUpdated=True, UpdateSourceTrigger=PropertyChanged}"
|
||||
|
|
|
@ -27,23 +27,18 @@
|
|||
</Style.Triggers>
|
||||
</Style>
|
||||
<Style x:Key="ProfileAddPlaneBindingDependency" TargetType="Button" BasedOn="{StaticResource {x:Type Button}}">
|
||||
<Setter Property="Content" Value="Add Binding"/>
|
||||
<Setter Property="Width" Value="130"/>
|
||||
<Setter Property="IsEnabled" Value="False"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{c:Binding Path='DataStore.HasActiveUserProfileId and DataStore.HasCurrentMsfsPlaneTitle and DataStore.ActiveUserProfile.BindingPlaneTitle != DataStore.CurrentMsfsPlaneTitle', Mode=OneWay}" Value="True">
|
||||
<DataTrigger Binding="{c:Binding Path='DataStore.HasActiveUserProfileId and DataStore.HasCurrentMsfsPlaneTitle and DataStore.IsAllowedAddAircraftBinding', Mode=OneWay}" Value="True">
|
||||
<Setter Property="IsEnabled" Value="True"/>
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{c:Binding Path='DataStore.ActiveUserProfile.HasBindingPlaneTitle and DataStore.ActiveUserProfile.BindingPlaneTitle != DataStore.CurrentMsfsPlaneTitle', Mode=OneWay}" Value="True">
|
||||
<Setter Property="Content" Value="Replace Binding"/>
|
||||
<Setter Property="Width" Value="130"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
<Style x:Key="ProfileDeletePlaneBindingDependency" TargetType="Button" BasedOn="{StaticResource {x:Type Button}}">
|
||||
<Setter Property="IsEnabled" Value="False"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{c:Binding Path='DataStore.HasActiveUserProfileId and DataStore.ActiveUserProfile.HasBindingPlaneTitle', Mode=OneWay}" Value="True">
|
||||
<DataTrigger Binding="{c:Binding Path='DataStore.HasActiveUserProfileId and DataStore.ActiveUserProfile.HasBindingPlaneTitle and DataStore.IsAllowedDeleteAircraftBinding', Mode=OneWay}" Value="True">
|
||||
<Setter Property="IsEnabled" Value="True"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
|
@ -53,42 +48,71 @@
|
|||
<DockPanel>
|
||||
<WrapPanel DockPanel.Dock="Left" Orientation="Vertical" Margin="15,10,0,0" Width="585" HorizontalAlignment="Left">
|
||||
<Label Content="1. Please select a profile you would like to use." HorizontalAlignment="Left" />
|
||||
<WrapPanel Orientation="Horizontal" Margin="20,5,0,0" HorizontalAlignment="Left">
|
||||
<ComboBox HorizontalAlignment="Left"
|
||||
Margin="20,0,0,0"
|
||||
VerticalAlignment="Top"
|
||||
Width="485"
|
||||
VerticalAlignment="Center"
|
||||
Width="450"
|
||||
ItemsSource="{Binding Source={StaticResource UserProfilesViewSource}}"
|
||||
SelectedValue="{Binding Path=DataStore.ActiveUserProfileId}"
|
||||
DisplayMemberPath="ProfileName"
|
||||
SelectedValuePath="ProfileId"/>
|
||||
<WrapPanel Orientation="Horizontal" Margin="20,10,0,0" HorizontalAlignment="Left">
|
||||
<Button Content="Add Profile" HorizontalAlignment="Left" Width="130" Click="AddProfile_Click"/>
|
||||
<Button Content="Delete Profile" HorizontalAlignment="Left" Margin="20,0,0,0" Width="130" Click="DeleteProfile_Click" Style="{StaticResource ProfileSelectedDependency}"/>
|
||||
<Button Content="Set Default" HorizontalAlignment="Left" Margin="20,0,0,0" Width="130" Command="{Binding Path=SetDefaultProfileCommand}" Style="{StaticResource ProfileSelectedDependency}"/>
|
||||
<Button Content="+" ToolTip="Add Profile" HorizontalAlignment="Left" Margin="10,0,0,0" Width="40" Click="AddProfile_Click" />
|
||||
<Button Content="-" ToolTip="Delete Profile" HorizontalAlignment="Left" Margin="10,0,0,0" Width="40" Click="DeleteProfile_Click" Style="{StaticResource ProfileSelectedDependency}"/>
|
||||
<!--<Button Content="D" ToolTip="Set Default Profile" HorizontalAlignment="Left" Margin="10,0,0,0" Width="40" Command="{Binding Path=SetDefaultProfileCommand}" Style="{StaticResource ProfileSelectedDependency}"/>-->
|
||||
</WrapPanel>
|
||||
<WrapPanel Orientation="Horizontal" Margin="15,10,0,0" HorizontalAlignment="Left">
|
||||
<Label Content="Binding:" HorizontalAlignment="Left"/>
|
||||
<Label Content="{c:Binding Path='(DataStore.ActiveUserProfile.HasBindingPlaneTitle ? DataStore.ActiveUserProfile.BindingPlaneTitle : "None")'}" HorizontalContentAlignment="Left" HorizontalAlignment="Left" FontStyle="Italic" Foreground="LightGreen" />
|
||||
<Separator Margin="5,10,5,10"/>
|
||||
<Label Content="2. Optional: Bind active aircraft livery to profile to automatically pop out panels." HorizontalAlignment="Left" Margin="0,0,0,0" />
|
||||
<WrapPanel Orientation="Vertical" Margin="15,0,0,0" HorizontalAlignment="Left">
|
||||
<WrapPanel Orientation="Horizontal" Margin="5,5,0,0" HorizontalAlignment="Left">
|
||||
<Label Content="{c:Binding Path='DataStore.CurrentMsfsPlaneTitle == null ? "Active aircraft livery is unavailable" : DataStore.CurrentMsfsPlaneTitle'}" HorizontalContentAlignment="Left" HorizontalAlignment="Left" FontStyle="Italic" Width="450">
|
||||
<Label.Style>
|
||||
<Style TargetType="{x:Type Label}">
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{c:Binding Path='DataStore.IsAircraftBindedToProfile'}" Value="True">
|
||||
<Setter Property="Foreground" Value="LightGreen" ></Setter>
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{c:Binding Path='DataStore.IsAircraftBindedToProfile'}" Value="False">
|
||||
<Setter Property="Foreground" Value="AntiqueWhite" ></Setter>
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{c:Binding Path='!DataStore.IsAllowedAddAircraftBinding and !DataStore.IsAllowedDeleteAircraftBinding'}" Value="True">
|
||||
<Setter Property="Foreground" Value="Red" ></Setter>
|
||||
<Setter Property="ToolTip" Value="Aircraft Livery is currently binded to another profile"></Setter>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Label.Style>
|
||||
</Label>
|
||||
<Button Content="+" ToolTip="Add Bidning" Margin="10,0,0,0" Width="40" Click="AddBinding_Click" Style="{StaticResource ProfileAddPlaneBindingDependency}"/>
|
||||
<Button Content="-" ToolTip="Delete Binding" Margin="10,0,0,0" Width="40" Click="DeleteBinding_Click" Style="{StaticResource ProfileDeletePlaneBindingDependency}"/>
|
||||
</WrapPanel>
|
||||
<WrapPanel Orientation="Horizontal" Margin="20,5,0,0" HorizontalAlignment="Left">
|
||||
<Button HorizontalAlignment="Left" Click="AddBinding_Click" Style="{StaticResource ProfileAddPlaneBindingDependency}"/>
|
||||
<Button Content="Delete Binding" HorizontalAlignment="Left" Margin="20,0,0,0" Width="130" Click="DeleteBinding_Click" Style="{StaticResource ProfileDeletePlaneBindingDependency}"/>
|
||||
<CheckBox Margin="40,0,0,0" IsChecked="{Binding Path=DataStore.ActiveUserProfile.PowerOnRequiredForColdStart}" IsEnabled="{Binding Path=DataStore.HasActiveUserProfileId}" Command="{Binding Path=SetPowerOnRequiredCommand}">
|
||||
<TextBlock Text="Power on required to pop out panels on cold start" TextWrapping="Wrap" Width="200" Margin="5,0,0,3"/>
|
||||
<CheckBox Margin="10,5,0,0" IsChecked="{Binding Path=DataStore.ActiveUserProfile.PowerOnRequiredForColdStart}" IsEnabled="{Binding Path=DataStore.HasActiveUserProfileId}" Command="{Binding Path=SetPowerOnRequiredCommand}">
|
||||
<TextBlock Text="Power on required to pop out panels on cold start" TextWrapping="Wrap" Margin="5,0,0,3"/>
|
||||
</CheckBox>
|
||||
</WrapPanel>
|
||||
<Label Content="2. Identify pop out panel locations in the game by clicking on them." Margin="0,15,0,0" />
|
||||
<Separator Margin="5,10,5,10"/>
|
||||
<Label Content="3. Identify pop out panel locations in the game by clicking on them." Margin="0,0,0,0" />
|
||||
<WrapPanel Orientation="Vertical" Margin="20,0,0,0" HorizontalAlignment="Left">
|
||||
<Label Content="LEFT CLICK to add a new panel."/>
|
||||
<Label Content="CTRL + LEFT CLICK when all panels have been selected or to cancel selections." />
|
||||
<Label Content="SHIFT + LEFT CLICK to remove the most recently added panel."/>
|
||||
<WrapPanel Orientation="Horizontal" Margin="0,10,0,0" HorizontalAlignment="Left">
|
||||
<WrapPanel Orientation="Horizontal">
|
||||
<Label Content="LEFT CLICK" Foreground="AntiqueWhite"/>
|
||||
<Label Content="to add a new panel."/>
|
||||
</WrapPanel>
|
||||
|
||||
<WrapPanel Orientation="Horizontal">
|
||||
<Label Content="CTRL + LEFT CLICK" Foreground="AntiqueWhite" />
|
||||
<Label Content="when all panels have been selected or to cancel selections." />
|
||||
</WrapPanel>
|
||||
<WrapPanel Orientation="Horizontal">
|
||||
<Label Content="SHIFT + LEFT CLICK" Foreground="AntiqueWhite" />
|
||||
<Label Content="to remove the most recently added panel."/>
|
||||
</WrapPanel>
|
||||
<WrapPanel Orientation="Horizontal" Margin="0,5,0,0" HorizontalAlignment="Left">
|
||||
<Button Content="Start Panel Selection" HorizontalAlignment="Left" Margin="0,0,0,0" Width="165" Click="StartPanelSelection_Click" Style="{StaticResource ProfileSelectedDependency}"/>
|
||||
<Button Content="Save Auto Panning Camera" HorizontalAlignment="Left" Margin="20,0,0,0" IsEnabled="{c:Binding Path='DataStore.HasActiveUserProfileId and DataStore.IsFlightActive'}" Width="215" Click="SaveAutoPanningCamera_Click" Style="{StaticResource ProfileSelectedDependency}"/>
|
||||
</WrapPanel>
|
||||
</WrapPanel>
|
||||
<Label Content="3. Start the pop out process for selected panels." Margin="0,15,0,0" />
|
||||
<Button Content="Start Pop Out" HorizontalAlignment="Left" Margin="20,10,0,0" Width="130" IsEnabled="{c:Binding Path='DataStore.HasActiveUserProfileId and DataStore.IsFlightActive'}" Command="{Binding Path=StartPopOutCommand}" Style="{StaticResource ProfileSelectedDependency}"/>
|
||||
<Separator Margin="5,10,5,10"/>
|
||||
<Label Content="4. Start the pop out process for selected panels." Margin="0,0,0,0" />
|
||||
<Button Content="Start Pop Out" HorizontalAlignment="Left" Margin="20,5,0,0" Width="130" IsEnabled="{c:Binding Path='DataStore.HasActiveUserProfileId and DataStore.IsFlightActive'}" Command="{Binding Path=StartPopOutCommand}" Style="{StaticResource ProfileSelectedDependency}"/>
|
||||
</WrapPanel>
|
||||
<DockPanel DockPanel.Dock="Right" Width="325" HorizontalAlignment="Center">
|
||||
<Label DockPanel.Dock="Top" Content="Panel Locations" HorizontalAlignment="Center" Margin="0,10,0,0"/>
|
||||
|
|
|
@ -88,7 +88,7 @@ namespace MSFSPopoutPanelManager.WpfApp
|
|||
|
||||
private void AddBinding_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
ConfirmationDialog dialog = new ConfirmationDialog("Confirm Add Binding", $"Are you sure you want to bind the selected profile to the following plane? \n{_panelSelectionViewModel.DataStore.CurrentMsfsPlaneTitle}");
|
||||
ConfirmationDialog dialog = new ConfirmationDialog("Confirm Add Binding", $"Are you sure you want to bind the aircraft livery below to the active profile? \n{_panelSelectionViewModel.DataStore.CurrentMsfsPlaneTitle}");
|
||||
dialog.Owner = Application.Current.MainWindow;
|
||||
dialog.Topmost = true;
|
||||
dialog.WindowStartupLocation = WindowStartupLocation.CenterOwner;
|
||||
|
@ -101,7 +101,7 @@ namespace MSFSPopoutPanelManager.WpfApp
|
|||
|
||||
private void DeleteBinding_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
ConfirmationDialog dialog = new ConfirmationDialog("Confirm Delete Binding", $"Are you sure you want to delete the following binding for the selected profile? \n{_panelSelectionViewModel.DataStore.ActiveUserProfile.BindingPlaneTitle}");
|
||||
ConfirmationDialog dialog = new ConfirmationDialog("Confirm Delete Binding", $"Are you sure you want to delete aircraft livery binding below from the active profile? \n{_panelSelectionViewModel.DataStore.CurrentMsfsPlaneTitle}");
|
||||
dialog.Owner = Application.Current.MainWindow;
|
||||
dialog.Topmost = true;
|
||||
dialog.WindowStartupLocation = WindowStartupLocation.CenterOwner;
|
||||
|
|
|
@ -62,8 +62,14 @@ namespace MSFSPopoutPanelManager.WpfApp.ViewModel
|
|||
|
||||
_simConnectManager = new SimConnectManager();
|
||||
_simConnectManager.OnSimConnectDataRefreshed += (sender, e) =>
|
||||
{
|
||||
// Automatic switching of active profile when SimConnect active aircraft livery changes
|
||||
if(DataStore.CurrentMsfsPlaneTitle != e.Value.Title)
|
||||
{
|
||||
DataStore.CurrentMsfsPlaneTitle = e.Value.Title;
|
||||
AutoSwitchProfile(e.Value.Title);
|
||||
}
|
||||
|
||||
DataStore.ElectricalMasterBatteryStatus = e.Value.ElectricalMasterBattery;
|
||||
};
|
||||
_simConnectManager.OnConnected += (sender, e) => { DataStore.IsSimulatorStarted = true; };
|
||||
|
@ -242,22 +248,24 @@ namespace MSFSPopoutPanelManager.WpfApp.ViewModel
|
|||
{
|
||||
Debug.WriteLine("Flight Started");
|
||||
|
||||
Application.Current.Dispatcher.Invoke(() =>
|
||||
{
|
||||
AutoSwitchProfile(DataStore.CurrentMsfsPlaneTitle);
|
||||
|
||||
DataStore.IsEnteredFlight = true;
|
||||
ShowPanelSelection(true);
|
||||
|
||||
// find the profile with the matching binding plane title
|
||||
var profile = DataStore.UserProfiles.FirstOrDefault(p => p.BindingPlaneTitle == DataStore.CurrentMsfsPlaneTitle);
|
||||
var profile = DataStore.UserProfiles.FirstOrDefault(p => p.BindingPlaneTitle.ToList().Exists(p => p == DataStore.CurrentMsfsPlaneTitle));
|
||||
|
||||
if (profile != null)
|
||||
{
|
||||
Thread.Sleep(DataStore.AppSetting.AutoPopOutPanelsWaitDelay.ReadyToFlyButton * 1000); // Wait for the ready to fly button
|
||||
if (profile == null || profile.PanelSourceCoordinates.Count == 0)
|
||||
return;
|
||||
|
||||
var messageDialog = new OnScreenMessageDialog($"Automatic pop out is starting for profile:\n{profile.ProfileName}", DataStore.AppSetting.AutoPopOutPanelsWaitDelay.ReadyToFlyButton); // Wait for the ready to fly button
|
||||
messageDialog.ShowDialog();
|
||||
InputEmulationManager.LeftClickReadyToFly();
|
||||
|
||||
Application.Current.Dispatcher.Invoke(() =>
|
||||
{
|
||||
var messageDialog = new OnScreenMessageDialog($"Panel pop out in progress for profile:\n{profile.ProfileName}", DataStore.AppSetting.AutoPopOutPanelsWaitDelay.InitialCockpitView);
|
||||
messageDialog.ShowDialog();
|
||||
Thread.Sleep(DataStore.AppSetting.AutoPopOutPanelsWaitDelay.InitialCockpitView * 1000); // Wait for the initial cockpit view
|
||||
|
||||
// Turn on power if required to pop out panels
|
||||
_simConnectManager.TurnOnPower(profile.PowerOnRequiredForColdStart);
|
||||
|
@ -272,11 +280,11 @@ namespace MSFSPopoutPanelManager.WpfApp.ViewModel
|
|||
_simConnectManager.TurnOffpower();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleOnFlightStopped(object sender, EventArgs e)
|
||||
{
|
||||
DataStore.IsEnteredFlight = false;
|
||||
OnRestart(null);
|
||||
}
|
||||
|
||||
private void CheckForAutoUpdate()
|
||||
|
@ -285,10 +293,21 @@ namespace MSFSPopoutPanelManager.WpfApp.ViewModel
|
|||
AutoUpdater.PersistenceProvider = new JsonFilePersistenceProvider(jsonPath);
|
||||
AutoUpdater.Synchronous = true;
|
||||
AutoUpdater.AppTitle = "MSFS Pop Out Panel Manager";
|
||||
AutoUpdater.RunUpdateAsAdmin = false;
|
||||
//AutoUpdater.RunUpdateAsAdmin = false;
|
||||
AutoUpdater.UpdateFormSize = new System.Drawing.Size(930, 675);
|
||||
//AutoUpdater.Start("https://raw.githubusercontent.com/hawkeye-stan/msfs-popout-panel-manager/master/autoupdate.xml");
|
||||
AutoUpdater.Start("https://raw.githubusercontent.com/hawkeye-stan/AutoUpdateTest/main/autoupdate.xml");
|
||||
AutoUpdater.Start("https://raw.githubusercontent.com/hawkeye-stan/msfs-popout-panel-manager/master/autoupdate.xml");
|
||||
//AutoUpdater.Start("https://raw.githubusercontent.com/hawkeye-stan/AutoUpdateTest/main/autoupdate.xml");
|
||||
}
|
||||
|
||||
private void AutoSwitchProfile(string activeAircraftTitle)
|
||||
{
|
||||
// Automatic switching of active profile when SimConnect active aircraft livery changes
|
||||
if (DataStore.UserProfiles != null)
|
||||
{
|
||||
var matchedProfile = DataStore.UserProfiles.ToList().Find(p => p.BindingPlaneTitle.ToList().Exists(t => t == activeAircraftTitle));
|
||||
if (matchedProfile != null)
|
||||
DataStore.ActiveUserProfileId = matchedProfile.ProfileId;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -117,6 +117,47 @@ namespace MSFSPopoutPanelManager.WpfApp.ViewModel
|
|||
get { return !String.IsNullOrEmpty(CurrentMsfsPlaneTitle); }
|
||||
}
|
||||
|
||||
public bool IsAircraftBindedToProfile
|
||||
{
|
||||
get
|
||||
{
|
||||
if (ActiveUserProfile == null)
|
||||
return false;
|
||||
|
||||
return ActiveUserProfile.BindingPlaneTitle.ToList().Exists(p => p == CurrentMsfsPlaneTitle);
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsAllowedDeleteAircraftBinding
|
||||
{
|
||||
get
|
||||
{
|
||||
if (ActiveUserProfile == null || !HasCurrentMsfsPlaneTitle)
|
||||
return false;
|
||||
|
||||
var uProfile = UserProfiles.ToList().Find(u => u.BindingPlaneTitle.ToList().Exists(p => p == CurrentMsfsPlaneTitle));
|
||||
if (uProfile != null && uProfile.ProfileId != ActiveUserProfileId)
|
||||
return false;
|
||||
|
||||
return ActiveUserProfile.BindingPlaneTitle.ToList().Exists(p => p == CurrentMsfsPlaneTitle);
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsAllowedAddAircraftBinding
|
||||
{
|
||||
get
|
||||
{
|
||||
if (ActiveUserProfile == null || !HasCurrentMsfsPlaneTitle)
|
||||
return false;
|
||||
|
||||
var uProfile = UserProfiles.ToList().Find(u => u.BindingPlaneTitle.ToList().Exists(p => p == CurrentMsfsPlaneTitle));
|
||||
if (uProfile != null && uProfile.ProfileId != ActiveUserProfileId)
|
||||
return false;
|
||||
|
||||
return !ActiveUserProfile.BindingPlaneTitle.ToList().Exists(p => p == CurrentMsfsPlaneTitle);
|
||||
}
|
||||
}
|
||||
|
||||
public bool ElectricalMasterBatteryStatus { get; set; }
|
||||
|
||||
public bool IsSimulatorStarted { get; set; }
|
||||
|
|
|
@ -97,12 +97,24 @@ namespace MSFSPopoutPanelManager.WpfApp.ViewModel
|
|||
|
||||
private void OnAddProfileBinding(object commandParameter)
|
||||
{
|
||||
var index = DataStore.ActiveUserProfileId;
|
||||
|
||||
_userProfileManager.AddProfileBinding(DataStore.CurrentMsfsPlaneTitle, DataStore.ActiveUserProfileId);
|
||||
|
||||
// force profile refresh
|
||||
DataStore.ActiveUserProfileId = -1;
|
||||
DataStore.ActiveUserProfileId = index;
|
||||
}
|
||||
|
||||
private void OnDeleteProfileBinding(object commandParameter)
|
||||
{
|
||||
_userProfileManager.DeleteProfileBinding(DataStore.ActiveUserProfileId);
|
||||
var index = DataStore.ActiveUserProfileId;
|
||||
|
||||
_userProfileManager.DeleteProfileBinding(DataStore.CurrentMsfsPlaneTitle, DataStore.ActiveUserProfileId);
|
||||
|
||||
// force profile refresh
|
||||
DataStore.ActiveUserProfileId = -1;
|
||||
DataStore.ActiveUserProfileId = index;
|
||||
}
|
||||
|
||||
private void OnStartPanelSelection(object commandParameter)
|
||||
|
@ -150,7 +162,7 @@ namespace MSFSPopoutPanelManager.WpfApp.ViewModel
|
|||
var simualatorProcess = DiagnosticManager.GetSimulatorProcess();
|
||||
if (simualatorProcess != null && DataStore.IsFlightActive)
|
||||
{
|
||||
InputEmulationManager.SaveCustomViewZero(simualatorProcess.Handle);
|
||||
InputEmulationManager.SaveCustomView(simualatorProcess.Handle, DataStore.AppSetting.AutoPanningKeyBinding);
|
||||
Logger.LogStatus("Auto Panning Camera has been saved succesfully.", StatusMessageType.Info);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>net5.0-windows</TargetFramework>
|
||||
<UseWPF>true</UseWPF>
|
||||
<Version>3.2.0.0</Version>
|
||||
<Version>3.3.0.0</Version>
|
||||
<PackageId>MSFS 2020 Popout Panel Manager</PackageId>
|
||||
<Authors>Stanley Kwok</Authors>
|
||||
<Product>MSFS 2020 Popout Panel Manager</Product>
|
||||
|
@ -75,12 +75,19 @@
|
|||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Update="PreferencesDialog.xaml.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Update="UserControlPanelConfiguration.xaml.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Page Update="PreferencesDialog.xaml">
|
||||
<XamlRuntime>$(DefaultXamlRuntime)</XamlRuntime>
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Page Update="UserControlPanelConfiguration.xaml">
|
||||
<XamlRuntime>$(DefaultXamlRuntime)</XamlRuntime>
|
||||
<SubType>Designer</SubType>
|
||||
|
|
|
@ -1,17 +1,12 @@
|
|||
- Added per monitor DPI-awareness support. The application should run and display correctly when using combination of mixed monitor (with high-DPI and low-DPI) resolutions and scaling.
|
||||
Version 3.2.0.1 (v3.2 Release)
|
||||
|
||||
- Added system tray icon access. Application can start minimize or minimize to system tray. System tray icon features a context menu to allow quick access to application functions.
|
||||
- Added application auto update support. By installing this version of the app, auto update
|
||||
functionality will be available for all future versions of the application.
|
||||
|
||||
- Added user requested feature to provide keyboard shortcut (Ctrl-Alt-P) to start panel pop out with either an active profile or a default profile selected.
|
||||
- Disabled panel adjustments when Hide Title Bar is checked for a panel. This is to fix an
|
||||
issue where panel adjustments (X-Pos, Y-Pos, Width, and Height) will behave erratically when
|
||||
Hide Title Bar is checked.
|
||||
|
||||
- New copy profile feature. You can reuse your defined panel settings for another plane or plane/livery combination.
|
||||
|
||||
- Added quick panel location selection adjustment feature. You can now adjust panel locations without redoing the entire profile.
|
||||
|
||||
- Added Save Auto Panning Camera Angle function if you need to adjust the in-game camera angle during panel selection.
|
||||
|
||||
- Added application auto update feature.
|
||||
|
||||
- New logo icon for the app.
|
||||
|
||||
- New dark theme for the entire UI.
|
||||
- Increased default delay for auto-clicking "Ready to Fly" button from 2 seconds to 4 seconds
|
||||
in regard to Auto Pop Out Panels feature.
|
||||
[Fixed Issue #9] (https://github.com/hawkeye-stan/msfs-popout-panel-manager/issues/9
|
Loading…
Reference in a new issue