mirror of
https://github.com/hawkeye-stan/msfs-popout-panel-manager.git
synced 2024-11-21 13:20:11 +00:00
Squashed commit of the following:
commit 2bbda3c4e4969fdf05566908fde01f1c9e4e23f7 Author: Stanley <hawkeyesk@outlook.com> Date: Mon Sep 5 23:54:39 2022 -0400 Added in-game panel support commit ec29b0ec2612b10e45ab9a73c10b88a98fcf6eaf Author: Stanley <hawkeyesk@outlook.com> Date: Sun Sep 4 21:21:37 2022 -0400 Added in-game panel support commit 97edc184f349e1fde74a15a643fb90fb9bd90395 Author: Stanley <hawkeyesk@outlook.com> Date: Thu Sep 1 18:08:44 2022 -0400 Update touch panel commit da48ca0a272290466952c5c1bd1ca035d56f930c Author: Stanley <hawkeyesk@outlook.com> Date: Mon Aug 29 22:19:38 2022 -0400 Added pop out panel temporary display commit 701346193804f93616b0e6e2222d9d55223f516f Author: Stanley <hawkeyesk@outlook.com> Date: Wed Aug 24 10:33:59 2022 -0400 Added auto resize window display mode commit 98cbcd949f1555b44db22267ce5c54858bef47cd Author: Stanley <hawkeyesk@outlook.com> Date: Wed Aug 24 09:39:38 2022 -0400 Added auto resize window display mode
This commit is contained in:
parent
9555185274
commit
43caff1ca9
52 changed files with 633 additions and 885 deletions
3
Addons/InGameToolbar/.gitignore
vendored
3
Addons/InGameToolbar/.gitignore
vendored
|
@ -1,3 +0,0 @@
|
||||||
_Temp/
|
|
||||||
Packages/
|
|
||||||
PackagesMetadata/
|
|
Binary file not shown.
|
@ -1,30 +0,0 @@
|
||||||
<AssetPackage Name="pop-out-manager" Version="1.0.0">
|
|
||||||
<ItemSettings>
|
|
||||||
<ContentType>SPB</ContentType>
|
|
||||||
<Title>pop-out-manager</Title>
|
|
||||||
<Manufacturer>Stanley Kwok</Manufacturer>
|
|
||||||
<Creator>Stanley Kwok</Creator>
|
|
||||||
</ItemSettings>
|
|
||||||
<Flags>
|
|
||||||
<VisibleInStore>false</VisibleInStore>
|
|
||||||
<CanBeReferenced>false</CanBeReferenced>
|
|
||||||
</Flags>
|
|
||||||
<AssetGroups>
|
|
||||||
<AssetGroup Name="pop-out-manager">
|
|
||||||
<Type>SPB</Type>
|
|
||||||
<Flags>
|
|
||||||
<FSXCompatibility>false</FSXCompatibility>
|
|
||||||
</Flags>
|
|
||||||
<AssetDir>PackageSources\pop-out-manager\</AssetDir>
|
|
||||||
<OutputDir>InGamePanels\</OutputDir>
|
|
||||||
</AssetGroup>
|
|
||||||
<AssetGroup Name="html-ui">
|
|
||||||
<Type>Copy</Type>
|
|
||||||
<Flags>
|
|
||||||
<FSXCompatibility>false</FSXCompatibility>
|
|
||||||
</Flags>
|
|
||||||
<AssetDir>PackageSources\html_ui\</AssetDir>
|
|
||||||
<OutputDir>html_ui\</OutputDir>
|
|
||||||
</AssetGroup>
|
|
||||||
</AssetGroups>
|
|
||||||
</AssetPackage>
|
|
Binary file not shown.
|
@ -1,138 +0,0 @@
|
||||||
body.modal-open {
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
body.modal-open .stepDialog {
|
|
||||||
pointer-events: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
pop-out-manager #popOutManager .ingameUiWrapper .horizontalLayout {
|
|
||||||
background-color: var(--backgroundColorPanel);
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
padding: 1em 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
pop-out-manager #popOutManager .ingameUiWrapper .horizontalLayout #profileInfo {
|
|
||||||
flex: 1 1 0;
|
|
||||||
margin-bottom: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
pop-out-manager #popOutManager .ingameUiWrapper .horizontalLayout #panelConfigTable {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
border: solid 1px white;
|
|
||||||
flex: 20 1 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
pop-out-manager #popOutManager .ingameUiWrapper .horizontalLayout #panelConfigButtons {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
position: relative;
|
|
||||||
margin: 2em 1em 1em 1em;
|
|
||||||
flex: 2 1 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
pop-out-manager #popOutManager .ingameUiWrapper .panelConfigButton {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
width: 6em;
|
|
||||||
height: 3em;
|
|
||||||
margin-right: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
pop-out-manager #popOutManager .ingameUiWrapper .lockPanelsButton {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
position: absolute;
|
|
||||||
right: 0;
|
|
||||||
width: 10em;
|
|
||||||
height: 3em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.panelRow {
|
|
||||||
display: flex;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.panelRow .column1 {
|
|
||||||
width: 34%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.panelRow .column2 {
|
|
||||||
width: 8%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.panelRow .column3 {
|
|
||||||
width: 8%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.panelRow .column4 {
|
|
||||||
width: 8%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.panelRow .column5 {
|
|
||||||
width: 8%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.panelRow .column6 {
|
|
||||||
width: 8%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.panelRow .column7 {
|
|
||||||
width: 8%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.panelRow .column8 {
|
|
||||||
width: 10%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.panelRow .column9 {
|
|
||||||
width: 8%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.panelCell {
|
|
||||||
display: flex;
|
|
||||||
padding: 0.7em 1em;
|
|
||||||
margin: 0;
|
|
||||||
justify-content: center;
|
|
||||||
text-align: center;
|
|
||||||
border-bottom: solid 1px white;
|
|
||||||
border-right: solid 1px white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.panelCell:last-child {
|
|
||||||
border-right: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.panelCell .alignCenter {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.panelCell ui-input .default-input input {
|
|
||||||
padding-left: 0.25em;
|
|
||||||
padding-right: 0.25em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.panelCell checkbox-element .checkbox .choices .iconWrapper .icon {
|
|
||||||
width: 1.6em;
|
|
||||||
height: 1.6em;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.stepDialog {
|
|
||||||
display: none; /* Hidden by default */
|
|
||||||
position: fixed; /* Stay in place */
|
|
||||||
z-index: 1; /* Sit on top */
|
|
||||||
left: 20vw;
|
|
||||||
top: 20vh;
|
|
||||||
width: 60vw; /* Full width */
|
|
||||||
height: 60vh; /* Full height */
|
|
||||||
overflow: auto; /* Enable scroll if needed */
|
|
||||||
background-color: rgba(161, 153, 153, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -1,74 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8" />
|
|
||||||
<link rel="stylesheet" href="/SCSS/common.css" />
|
|
||||||
<link rel="stylesheet" href="PopOutManager.css" />
|
|
||||||
|
|
||||||
<script type="text/javascript" src="/JS/coherent.js"></script>
|
|
||||||
<script type="text/javascript" src="/JS/common.js"></script>
|
|
||||||
|
|
||||||
<script type="text/javascript" src="/JS/buttons.js"></script>
|
|
||||||
<script type="text/javascript" src="/JS/Services/ToolBarPanels.js"></script>
|
|
||||||
<script type="text/javascript" src="/JS/Services/Notifications.js"></script>
|
|
||||||
|
|
||||||
<link rel="import" href="/templates/virtualScroll/virtualScroll.html" />
|
|
||||||
<link rel="import" href="/templates/NewPushButton/NewPushButton.html" />
|
|
||||||
<link rel="import" href="/templates/DropDown/DropDown.html" />
|
|
||||||
<link rel="import" href="/templates/tabMenu/tabMenu.html" />
|
|
||||||
<link rel="import" href="/templates/ingameUi/ingameUi.html" />
|
|
||||||
<link rel="import" href="/templates/ingameUiHeader/ingameUiHeader.html" />
|
|
||||||
<link rel="import" href="/templates/checkbox/checkbox.html" />
|
|
||||||
<link rel="import" href="/templates/uiInput/uiInput.html" />
|
|
||||||
|
|
||||||
|
|
||||||
<script type="text/javascript" src="PopOutManager.js"></script>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body class="border-box">
|
|
||||||
<pop-out-manager>
|
|
||||||
<ingame-ui id="popOutManager" panel-id="PANEL_POP_OUT_MANAGER" title=""
|
|
||||||
class="ingameUiFrame panelInvisible condensedPanel" resize="both" min-width="160" min-height="90"
|
|
||||||
content-fit="true" auto-inside>
|
|
||||||
|
|
||||||
|
|
||||||
<div id="panelSelection" class="horizontalLayout" style="display:block">
|
|
||||||
<div id="profileInfo">Panel Locations and Settings - <span id="planeProfileName"></span></div>
|
|
||||||
<div id="panelSelection">
|
|
||||||
Panel Selection
|
|
||||||
<drop-down id="dropdownProfile" style="width:50vw"></drop-down>
|
|
||||||
<icon-button id="addProfile" data-url="/icons/open.svg"></icon-button>
|
|
||||||
<icon-button id="deleteProfile" data-url="/icons/reduce.svg"></icon-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div id="panelConfiguration" class="horizontalLayout" style="display:none">
|
|
||||||
<div id="profileInfo">Panel Locations and Settings - <span id="planeProfileName"></span></div>
|
|
||||||
<virtual-scroll id="panelConfigTable" direction="y">
|
|
||||||
</virtual-scroll>
|
|
||||||
<div id="panelConfigButtons">
|
|
||||||
<new-push-button id="btnMinusTen" title="-10 px" class="panelConfigButton"></new-push-button>
|
|
||||||
<new-push-button id="btnMinusOne" title="-1 px" class="panelConfigButton"></new-push-button>
|
|
||||||
<new-push-button id="btnPlusOne" title="+1 px" class="panelConfigButton"></new-push-button>
|
|
||||||
<new-push-button id="btnPlusTen" title="+10 px" class="panelConfigButton" toolTip="test"></new-push-button>
|
|
||||||
<div>
|
|
||||||
<new-push-button id="btnLockPanels" title="Lock Panels" class="lockPanelsButton"></new-push-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</ingame-ui>
|
|
||||||
</pop-out-manager>
|
|
||||||
|
|
||||||
|
|
||||||
<div id="dialogBegin" class="stepDialog">
|
|
||||||
<new-push-button id="btnStartPopOut" parentStep="stepBegin" title="Start Pop Out" class="stepButton"></new-push-button>
|
|
||||||
<new-push-button id="btnCreateNewProfile" parentStep="stepBegin" title="Create New Profile" class="stepButton"></new-push-button>
|
|
||||||
<new-push-button id="btnAdjustProfile" parentStep="stepBegin" title="Adjust Profile" class="stepButton"></new-push-button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
|
@ -1,388 +0,0 @@
|
||||||
class PopOutManagerPanelElement extends UIElement {
|
|
||||||
constructor() {
|
|
||||||
super(...arguments);
|
|
||||||
this.ingameUi = null;
|
|
||||||
this.isInitialized = false;
|
|
||||||
this.panelActive = false;
|
|
||||||
this.webSocket = null;
|
|
||||||
this.webSocketConnected = false;
|
|
||||||
this.webSocketInterval = null;
|
|
||||||
|
|
||||||
this.tryConnectWebSocket = () => {
|
|
||||||
this.lockPanel(true);
|
|
||||||
|
|
||||||
this.webSocket = new WebSocket("ws://localhost:27011/ws");
|
|
||||||
|
|
||||||
this.webSocket.onopen = () => {
|
|
||||||
clearInterval(this.webSocketInterval);
|
|
||||||
this.webSocketConnected = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
this.webSocket.onclose = () => {
|
|
||||||
this.webSocketConnected = false;
|
|
||||||
|
|
||||||
// Clear panel table
|
|
||||||
this.createPanelConfigTableHeader(this.panelConfigTable);
|
|
||||||
this.lockPanel(true);
|
|
||||||
|
|
||||||
this.webSocketInterval = setInterval(() => {
|
|
||||||
if (!this.webSocketConnected)
|
|
||||||
this.tryConnectWebSocket();
|
|
||||||
}, 2000)
|
|
||||||
};
|
|
||||||
|
|
||||||
this.webSocket.onerror = () => {
|
|
||||||
this.webSocket.close();
|
|
||||||
};
|
|
||||||
|
|
||||||
this.webSocket.onmessage = (event) => {
|
|
||||||
if (event.data !== undefined) {
|
|
||||||
|
|
||||||
var panelData = JSON.parse(event.data);
|
|
||||||
|
|
||||||
// only recreate panel rows if panel is refreshed (minimize/maximize, pop out)
|
|
||||||
if (this.panelActive && document.getElementsByClassName("panelRow").length == 1)
|
|
||||||
this.createPanelConfigTableBody(this.panelConfigTable, panelData);
|
|
||||||
|
|
||||||
if (panelData !== undefined && panelData !== null && panelData.length !== 0) {
|
|
||||||
this.lockPanel(false);
|
|
||||||
this.bindPanelData(panelData);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
this.webSocketInterval = setInterval(() => {
|
|
||||||
if (!this.webSocketConnected)
|
|
||||||
this.tryConnectWebSocket();
|
|
||||||
}, 2000)
|
|
||||||
}
|
|
||||||
|
|
||||||
connectedCallback() {
|
|
||||||
super.connectedCallback();
|
|
||||||
|
|
||||||
this.ingameUi = this.querySelector('ingame-ui');
|
|
||||||
this.panelSelection = document.getElementById("panelSelection");
|
|
||||||
this.panelConfiguration = document.getElementById("panelConfiguration");
|
|
||||||
this.planeProfileName = document.getElementById("planeProfileName");
|
|
||||||
this.panelConfigTable = document.getElementById("panelConfigTable");
|
|
||||||
this.btnLockPanels = this.querySelector('#btnLockPanels');
|
|
||||||
this.btnPlusTen = this.querySelector('#btnPlusTen');
|
|
||||||
this.btnPlusOne = this.querySelector('#btnPlusOne');
|
|
||||||
this.btnMinusTen = this.querySelector('#btnMinusTen');
|
|
||||||
this.btnMinusOne = this.querySelector('#btnMinusOne');
|
|
||||||
|
|
||||||
this.dropdownProfile = this.querySelector("#dropdownProfile");
|
|
||||||
this.addProfile = document.getElementById("addProfile");
|
|
||||||
this.deleteProfile = document.getElementById("deleteProfile");
|
|
||||||
|
|
||||||
this.stepBeginDialog = document.getElementById("stepBeginDialog");
|
|
||||||
|
|
||||||
|
|
||||||
this.closeDialog = document.getElementById("closeDialog");
|
|
||||||
|
|
||||||
//this.deleteProfile.disable(!this.deleteProfile.disabled);
|
|
||||||
|
|
||||||
//this.dropdownProfile.addEventListener("select", (event) = {});
|
|
||||||
|
|
||||||
let workflow = new Workflow(this);
|
|
||||||
workflow.bindAllButtonEvents();
|
|
||||||
workflow.stepBegin();
|
|
||||||
|
|
||||||
|
|
||||||
this.addProfile.addEventListener("click", (event) => {
|
|
||||||
addProfileDialog.style.display = "block";
|
|
||||||
//this.ingameUi.toggleExternPanel(true);
|
|
||||||
document.body.classList.toggle('modal-open');
|
|
||||||
|
|
||||||
// let value = new DataValue;
|
|
||||||
// value.name = "New Profile " + dropDownValues.length;
|
|
||||||
// value.ID = dropDownValues.length;
|
|
||||||
// dropDownValues.push(value);
|
|
||||||
// this.dropdownProfile.setData(dropDownValues, dropDownValues.length - 1);
|
|
||||||
});
|
|
||||||
|
|
||||||
this.deleteProfile.addEventListener("click", (event) => {
|
|
||||||
// dropDownValues.splice(-1,1);
|
|
||||||
// this.dropdownProfile.setData(dropDownValues, dropDownValues.length - 1);
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
this.isLocked = false;
|
|
||||||
|
|
||||||
let profiles = ["Kodiak", "172", "737"];
|
|
||||||
let dropDownValues = [];
|
|
||||||
profiles.forEach((profile, index) => {
|
|
||||||
let value = new DataValue;
|
|
||||||
value.name = profile;
|
|
||||||
value.ID = index;
|
|
||||||
dropDownValues.push(value);
|
|
||||||
});
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
this.dropdownProfile.setData(dropDownValues, 2)
|
|
||||||
|
|
||||||
|
|
||||||
}, 1000);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
this.btnLockPanels.addEventListener("click", () => {
|
|
||||||
if (this.btnLockPanels.disabled)
|
|
||||||
return;
|
|
||||||
|
|
||||||
this.isLocked = !this.isLocked;
|
|
||||||
|
|
||||||
this.lockPanel(this.isLocked);
|
|
||||||
|
|
||||||
if (this.isLocked) {
|
|
||||||
this.btnLockPanels.disabled = false;
|
|
||||||
this.btnLockPanels.title = "Unlock Panels";
|
|
||||||
this.btnLockPanels.style.backgroundColor = "red";
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.btnLockPanels.disabled = false;
|
|
||||||
this.btnLockPanels.title = "Lock Panels";
|
|
||||||
this.btnLockPanels.style.backgroundColor = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.panelSelection.style.display = 'block';
|
|
||||||
this.panelConfiguration.style.display = 'none';
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
if (this.ingameUi) {
|
|
||||||
this.ingameUi.addEventListener("panelActive", (e) => {
|
|
||||||
//document.getElementsByClassName("Extern")[0].style.display = "none"; // disable extern button
|
|
||||||
this.createPanelConfigTableHeader(this.panelConfigTable);
|
|
||||||
|
|
||||||
this.panelActive = true;
|
|
||||||
this.lockPanel(true);
|
|
||||||
|
|
||||||
if (this.webSocketConnected)
|
|
||||||
this.webSocket.send("RequestPanelData");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
createPanelConfigTableHeader(panelConfigTable) {
|
|
||||||
let panelRow;
|
|
||||||
|
|
||||||
// remove all child of panelConfigTable
|
|
||||||
while (panelConfigTable.firstChild) {
|
|
||||||
panelConfigTable.removeChild(panelConfigTable.firstChild);
|
|
||||||
}
|
|
||||||
|
|
||||||
// create header
|
|
||||||
panelRow = this.createPanelRow(true);
|
|
||||||
panelRow.appendChild(this.createPanelCell("div", "column1", "Panel Name"));
|
|
||||||
panelRow.appendChild(this.createPanelCell("div", "column2", "X-Pos"));
|
|
||||||
panelRow.appendChild(this.createPanelCell("div", "column3", "Y-Pos"));
|
|
||||||
panelRow.appendChild(this.createPanelCell("div", "column4", "Width"));
|
|
||||||
panelRow.appendChild(this.createPanelCell("div", "column5", "Height"));
|
|
||||||
panelRow.appendChild(this.createPanelCell("div", "column6", "Always on Top"));
|
|
||||||
panelRow.appendChild(this.createPanelCell("div", "column7", "Hide Title Bar"));
|
|
||||||
panelRow.appendChild(this.createPanelCell("div", "column8", "Full Screen Mode"));
|
|
||||||
panelRow.appendChild(this.createPanelCell("div", "column9", "Touch Enabled"));
|
|
||||||
panelConfigTable.appendChild(panelRow);
|
|
||||||
}
|
|
||||||
|
|
||||||
createPanelConfigTableBody(panelConfigTable, panelData) {
|
|
||||||
let panelRow;
|
|
||||||
|
|
||||||
if (panelConfigTable !== undefined) {
|
|
||||||
for (let index = 0; index < panelData.length; index++) {
|
|
||||||
panelRow = this.createPanelRow(false);
|
|
||||||
panelRow.appendChild(this.createPanelCell("div", "column1", this.createUiInput("PanelName_" + index)));
|
|
||||||
panelRow.appendChild(this.createPanelCell("div", "column2", this.createUiInput("XPos_" + index)));
|
|
||||||
panelRow.appendChild(this.createPanelCell("div", "column3", this.createUiInput("YPos_" + index)));
|
|
||||||
panelRow.appendChild(this.createPanelCell("div", "column4", this.createUiInput("Width_" + index)));
|
|
||||||
panelRow.appendChild(this.createPanelCell("div", "column5", this.createUiInput("Height_" + index)));
|
|
||||||
panelRow.appendChild(this.createPanelCell("div", "column6", this.createCheckbox("AlwaysOnTop_" + index)));
|
|
||||||
panelRow.appendChild(this.createPanelCell("div", "column7", this.createCheckbox("HideTitleBar_" + index)));
|
|
||||||
panelRow.appendChild(this.createPanelCell("div", "column8", this.createCheckbox("FullScreenMode_" + index)));
|
|
||||||
panelRow.appendChild(this.createPanelCell("div", "column9", this.createCheckbox("TouchEnabled_" + index)));
|
|
||||||
panelConfigTable.appendChild(panelRow);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
createPanelRow(isHeaderRow) {
|
|
||||||
let panelRow = document.createElement("div");
|
|
||||||
|
|
||||||
if (isHeaderRow)
|
|
||||||
panelRow.classList.add("panelHeaderRow");
|
|
||||||
|
|
||||||
panelRow.classList.add("panelRow");
|
|
||||||
|
|
||||||
return panelRow;
|
|
||||||
}
|
|
||||||
|
|
||||||
createPanelCell(cellType, classes = null, childElement) {
|
|
||||||
let cell = document.createElement(cellType);
|
|
||||||
cell.classList.add("panelCell");
|
|
||||||
|
|
||||||
if (classes !== undefined || classes !== null) {
|
|
||||||
if (typeof (classes) === "string") {
|
|
||||||
cell.classList.add(classes);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
for (let index = 0; index < classes.length; index++)
|
|
||||||
cell.classList.add(classes[index]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof (childElement) === "string")
|
|
||||||
cell.innerHTML = `<div class='alignCenter'>${childElement}</div>`;
|
|
||||||
else
|
|
||||||
cell.appendChild(childElement);
|
|
||||||
|
|
||||||
return cell;
|
|
||||||
}
|
|
||||||
|
|
||||||
createUiInput(id) {
|
|
||||||
let input = document.createElement("ui-input");
|
|
||||||
input.type = "text";
|
|
||||||
input.id = id;
|
|
||||||
return input;
|
|
||||||
}
|
|
||||||
|
|
||||||
createCheckbox(id) {
|
|
||||||
let checkbox = document.createElement("checkbox-element");
|
|
||||||
checkbox.id = id;
|
|
||||||
checkbox.style.width = "1em";
|
|
||||||
return checkbox;
|
|
||||||
}
|
|
||||||
|
|
||||||
lockPanel(isLocked) {
|
|
||||||
if (this.panelActive) {
|
|
||||||
let uiInputs = document.getElementsByTagName("ui-input");
|
|
||||||
for (let index = 0; index < uiInputs.length; index++) {
|
|
||||||
uiInputs[index].disabled = isLocked;
|
|
||||||
}
|
|
||||||
|
|
||||||
let checkboxes = document.getElementsByTagName("checkbox-element");
|
|
||||||
for (let index = 0; index < checkboxes.length; index++) {
|
|
||||||
checkboxes[index].SetData({ sTitle: "", bToggled: checkboxes.toggled, bDisabled: isLocked });
|
|
||||||
checkboxes[index].RefreshValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
this.btnLockPanels.disabled = isLocked;
|
|
||||||
if(isLocked)
|
|
||||||
{
|
|
||||||
this.btnLockPanels.title = "Lock Panels";
|
|
||||||
this.btnLockPanels.style.backgroundColor = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.btnPlusTen.disabled = isLocked;
|
|
||||||
this.btnPlusOne.disabled = isLocked;
|
|
||||||
this.btnMinusTen.disabled = isLocked;
|
|
||||||
this.btnMinusOne.disabled = isLocked;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bindPanelData(panelData) {
|
|
||||||
if (this.panelActive) {
|
|
||||||
panelData.forEach((panel, index) => {
|
|
||||||
this.bindUiInput("PanelName_" + index, panel.panelName, "text");
|
|
||||||
this.bindUiInput("XPos_" + index, panel.xPos);
|
|
||||||
this.bindUiInput("YPos_" + index, panel.yPos);
|
|
||||||
this.bindUiInput("Width_" + index, panel.width);
|
|
||||||
this.bindUiInput("Height_" + index, panel.height);
|
|
||||||
this.bindCheckbox("AlwaysOnTop_" + index, panel.alwaysOnTop);
|
|
||||||
this.bindCheckbox("HideTitleBar_" + index, panel.hideTitleBar);
|
|
||||||
this.bindCheckbox("FullScreenMode_" + index, panel.fullScreenMode);
|
|
||||||
this.bindCheckbox("TouchEnabled_" + index, panel.touchEnabled);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bindUiInput(id, value, type) {
|
|
||||||
let input = document.getElementById(id);
|
|
||||||
input.style.width = "100%";
|
|
||||||
input.setValue(value);
|
|
||||||
|
|
||||||
if (type === "text")
|
|
||||||
input.children[0].children[0].style.textAlign = "left";
|
|
||||||
}
|
|
||||||
|
|
||||||
bindCheckbox(id, value) {
|
|
||||||
let checkbox = document.getElementById(id);
|
|
||||||
checkbox.SetData({ sTitle: "", bToggled: value, bDisabled: false });
|
|
||||||
checkbox.RefreshValue();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
window.customElements.define("pop-out-manager", PopOutManagerPanelElement);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Workflow {
|
|
||||||
constructor(owner) {
|
|
||||||
this.owner = owner;
|
|
||||||
}
|
|
||||||
|
|
||||||
get workflowSteps() {
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
name: 'stepBegin',
|
|
||||||
results:
|
|
||||||
[
|
|
||||||
{ value: 'stepCreateNewProfile' },
|
|
||||||
{ value: 'stepStartPopOut' },
|
|
||||||
{ value: 'stepAdjustProfile' }
|
|
||||||
]
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
|
|
||||||
getFuncName() {
|
|
||||||
return this.getFuncName.caller.name;
|
|
||||||
}
|
|
||||||
|
|
||||||
bindAllButtonEvents(){
|
|
||||||
let stepButtons = document.getElementsByClassName("stepButton");
|
|
||||||
Array.from(stepButtons).forEach(btn => {
|
|
||||||
btn.addEventListener("click", (e) => {
|
|
||||||
let parentStep = e.target.getAttribute("parentStep");
|
|
||||||
let resultValue = e.target.id.replace("btn", "step");
|
|
||||||
this.handleButtonClick(parentStep, resultValue);
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
handleButtonClick(currentStep, resultValue) {
|
|
||||||
let step = this.workflowSteps.find(c => c.name == currentStep);
|
|
||||||
let result = step.results.find(f => f.value == resultValue);
|
|
||||||
|
|
||||||
if(result != null)
|
|
||||||
{
|
|
||||||
let func = this[result.value];
|
|
||||||
func();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
openDialog(step)
|
|
||||||
{
|
|
||||||
this.owner.stepBeginDialog = document.getElementById(step.replace("step", "dialog"));
|
|
||||||
this.owner.stepBeginDialog.style.display = "block";
|
|
||||||
document.body.classList.toggle("modal-open");
|
|
||||||
}
|
|
||||||
|
|
||||||
stepBegin() {
|
|
||||||
this.openDialog("stepBegin");
|
|
||||||
}
|
|
||||||
|
|
||||||
stepStartPopOut() {
|
|
||||||
var a = ""
|
|
||||||
}
|
|
||||||
|
|
||||||
stepCreateNewProfile() {
|
|
||||||
var a = ""
|
|
||||||
}
|
|
||||||
|
|
||||||
stepAdjustProfile() {
|
|
||||||
var a = ""
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,16 +0,0 @@
|
||||||
<?xml version="1.0" standalone="no"?>
|
|
||||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
|
||||||
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
|
||||||
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
|
||||||
width="64.000000pt" height="64.000000pt" viewBox="0 0 64.000000 64.000000"
|
|
||||||
preserveAspectRatio="xMidYMid meet">
|
|
||||||
|
|
||||||
<g transform="translate(0.000000,64.000000) scale(0.100000,-0.100000)"
|
|
||||||
fill="#000000" stroke="none">
|
|
||||||
<path d="M160 315 l0 -165 160 0 160 0 0 50 c0 43 -3 50 -20 50 -16 0 -20 -7
|
|
||||||
-20 -30 l0 -30 -120 0 -120 0 0 125 0 125 30 0 c23 0 30 4 30 20 0 17 -7 20
|
|
||||||
-50 20 l-50 0 0 -165z"/>
|
|
||||||
<path d="M358 447 l32 -33 -50 -49 c-47 -46 -49 -50 -33 -67 16 -18 19 -17 68
|
|
||||||
32 l51 50 27 -27 27 -28 0 78 0 77 -77 0 -77 0 32 -33z"/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 740 B |
|
@ -1,29 +0,0 @@
|
||||||
{
|
|
||||||
"content": [
|
|
||||||
{
|
|
||||||
"path": "html_ui/icons/toolbar/POP_OUT_MANAGER.svg",
|
|
||||||
"size": 740,
|
|
||||||
"date": 133013771715368552
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "html_ui/InGamePanels/PopOutManagerPanel/PopOutManager.css",
|
|
||||||
"size": 1921,
|
|
||||||
"date": 133015501657300878
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "html_ui/InGamePanels/PopOutManagerPanel/PopOutManager.html",
|
|
||||||
"size": 3194,
|
|
||||||
"date": 133023923647110813
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "html_ui/InGamePanels/PopOutManagerPanel/PopOutManager.js",
|
|
||||||
"size": 10854,
|
|
||||||
"date": 133023924937932717
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "InGamePanels/pop-out-manager.spb",
|
|
||||||
"size": 684,
|
|
||||||
"date": 133023927549810418
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
|
@ -1,15 +0,0 @@
|
||||||
{
|
|
||||||
"dependencies": [],
|
|
||||||
"content_type": "UNKNOWN",
|
|
||||||
"title": "pop-out-manager",
|
|
||||||
"manufacturer": "Stanley Kwok",
|
|
||||||
"creator": "Stanley Kwok",
|
|
||||||
"package_version": "1.0.0",
|
|
||||||
"minimum_game_version": "1.27.9",
|
|
||||||
"release_notes": {
|
|
||||||
"neutral": {
|
|
||||||
"LastUpdate": "",
|
|
||||||
"OlderHistory": ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,6 +0,0 @@
|
||||||
<?xml version="1.0" encoding="Windows-1252"?>
|
|
||||||
<SimBase.Document Type="InGamePanels" version="1,0">
|
|
||||||
<Filename>InGamePanel_PopOutManager.spb</Filename>
|
|
||||||
<InGamePanels.InGamePanelDefinition id="PANEL_POP_OUT_MANAGER" Name="Pop Out Manager" url="html_UI/ingamePanels/PopOutManagerPanel/PopOutManager.html" resizeDirections="Both" minWidth="80" minHeight="40" defaultWidth="120" defaultHeight="50" defaultTop="30" defaultLeft="5" icon="POP_OUT_MANAGER" buttonVisible="true">
|
|
||||||
</InGamePanels.InGamePanelDefinition>
|
|
||||||
</SimBase.Document>
|
|
|
@ -1 +0,0 @@
|
||||||
FOR %%i IN (*.xml) DO "%MSFS_SDK%\Tools\bin\fspackagetool.exe" %%i
|
|
Binary file not shown.
Before Width: | Height: | Size: 2.2 KiB |
|
@ -1,7 +0,0 @@
|
||||||
<Project Version="2" Name="pop-out-manager" FolderName="Packages">
|
|
||||||
<OutputDirectory>.</OutputDirectory>
|
|
||||||
<TemporaryOutputDirectory>_Temp</TemporaryOutputDirectory>
|
|
||||||
<Packages>
|
|
||||||
<Package>PackageDefinitions\pop-out-manager.xml</Package>
|
|
||||||
</Packages>
|
|
||||||
</Project>
|
|
|
@ -10,9 +10,9 @@
|
||||||
<PackageProjectUrl>https://github.com/hawkeye-stan/msfs-popout-panel-manager</PackageProjectUrl>
|
<PackageProjectUrl>https://github.com/hawkeye-stan/msfs-popout-panel-manager</PackageProjectUrl>
|
||||||
<RootNamespace>MSFSPopoutPanelManager.ArduinoAgent</RootNamespace>
|
<RootNamespace>MSFSPopoutPanelManager.ArduinoAgent</RootNamespace>
|
||||||
<Platforms>x64</Platforms>
|
<Platforms>x64</Platforms>
|
||||||
<Version>3.4.2.0</Version>
|
<Version>3.4.3.0</Version>
|
||||||
<AssemblyVersion>3.4.2.0</AssemblyVersion>
|
<AssemblyVersion>3.4.3.0</AssemblyVersion>
|
||||||
<FileVersion>3.4.2.0</FileVersion>
|
<FileVersion>3.4.3.0</FileVersion>
|
||||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||||
<DebugType>Embedded</DebugType>
|
<DebugType>Embedded</DebugType>
|
||||||
<Configurations>Debug;Release;DebugTouchPanel;ReleaseTouchPanel</Configurations>
|
<Configurations>Debug;Release;DebugTouchPanel;ReleaseTouchPanel</Configurations>
|
||||||
|
|
|
@ -9,8 +9,12 @@ namespace MSFSPopoutPanelManager.Orchestration
|
||||||
{
|
{
|
||||||
public class MainOrchestrator : ObservableObject
|
public class MainOrchestrator : ObservableObject
|
||||||
{
|
{
|
||||||
|
private IntPtr _msfsGameWindowHandle;
|
||||||
|
|
||||||
public MainOrchestrator()
|
public MainOrchestrator()
|
||||||
{
|
{
|
||||||
|
_msfsGameWindowHandle = IntPtr.Zero;
|
||||||
|
|
||||||
Profile = new ProfileOrchestrator();
|
Profile = new ProfileOrchestrator();
|
||||||
PanelSource = new PanelSourceOrchestrator();
|
PanelSource = new PanelSourceOrchestrator();
|
||||||
PanelPopOut = new PanelPopOutOrchestrator();
|
PanelPopOut = new PanelPopOutOrchestrator();
|
||||||
|
|
|
@ -10,9 +10,9 @@
|
||||||
<PackageProjectUrl>https://github.com/hawkeye-stan/msfs-popout-panel-manager</PackageProjectUrl>
|
<PackageProjectUrl>https://github.com/hawkeye-stan/msfs-popout-panel-manager</PackageProjectUrl>
|
||||||
<RootNamespace>MSFSPopoutPanelManager.Orchestration</RootNamespace>
|
<RootNamespace>MSFSPopoutPanelManager.Orchestration</RootNamespace>
|
||||||
<Platforms>x64</Platforms>
|
<Platforms>x64</Platforms>
|
||||||
<Version>3.4.2.0</Version>
|
<Version>3.4.3.0</Version>
|
||||||
<AssemblyVersion>3.4.2.0</AssemblyVersion>
|
<AssemblyVersion>3.4.3.0</AssemblyVersion>
|
||||||
<FileVersion>3.4.2.0</FileVersion>
|
<FileVersion>3.4.3.0</FileVersion>
|
||||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||||
<DebugType>Embedded</DebugType>
|
<DebugType>Embedded</DebugType>
|
||||||
<Configurations>Debug;Release;DebugTouchPanel;ReleaseTouchPanel</Configurations>
|
<Configurations>Debug;Release;DebugTouchPanel;ReleaseTouchPanel</Configurations>
|
||||||
|
|
|
@ -15,6 +15,7 @@ namespace MSFSPopoutPanelManager.Orchestration
|
||||||
{
|
{
|
||||||
// This will be replaced by a signal from Ready to Fly Skipper into webserver in version 4.0
|
// This will be replaced by a signal from Ready to Fly Skipper into webserver in version 4.0
|
||||||
private const int READY_TO_FLY_BUTTON_APPEARANCE_DELAY = 2000;
|
private const int READY_TO_FLY_BUTTON_APPEARANCE_DELAY = 2000;
|
||||||
|
private int _builtInPanelConfigDelay;
|
||||||
|
|
||||||
internal ProfileData ProfileData { get; set; }
|
internal ProfileData ProfileData { get; set; }
|
||||||
|
|
||||||
|
@ -35,6 +36,7 @@ namespace MSFSPopoutPanelManager.Orchestration
|
||||||
public event EventHandler OnPopOutStarted;
|
public event EventHandler OnPopOutStarted;
|
||||||
public event EventHandler<bool> OnPopOutCompleted;
|
public event EventHandler<bool> OnPopOutCompleted;
|
||||||
public event EventHandler<TouchPanelOpenEventArg> OnTouchPanelOpened;
|
public event EventHandler<TouchPanelOpenEventArg> OnTouchPanelOpened;
|
||||||
|
public event EventHandler<PanelSourceCoordinate> OnPanelSourceOverlayFlashed;
|
||||||
|
|
||||||
public void ManualPopOut()
|
public void ManualPopOut()
|
||||||
{
|
{
|
||||||
|
@ -43,9 +45,10 @@ namespace MSFSPopoutPanelManager.Orchestration
|
||||||
|
|
||||||
InputHookManager.EndHook();
|
InputHookManager.EndHook();
|
||||||
|
|
||||||
if (ActiveProfile.PanelSourceCoordinates.Count > 0 || ActiveProfile.TouchPanelBindings.Count > 0)
|
if (ActiveProfile.PanelSourceCoordinates.Count > 0 || ActiveProfile.TouchPanelBindings.Count > 0 || ActiveProfile.IncludeInGamePanels)
|
||||||
{
|
{
|
||||||
StatusMessageWriter.WriteMessage($"Panels pop out in progress for profile:\n{ActiveProfile.ProfileName}", StatusMessageType.Info, true);
|
StatusMessageWriter.WriteMessage($"Panels pop out in progress for profile:\n{ActiveProfile.ProfileName}", StatusMessageType.Info, true);
|
||||||
|
_builtInPanelConfigDelay = 0;
|
||||||
CorePopOutSteps();
|
CorePopOutSteps();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -67,19 +70,24 @@ namespace MSFSPopoutPanelManager.Orchestration
|
||||||
// Match the delay for Ready to Fly button to disappear
|
// Match the delay for Ready to Fly button to disappear
|
||||||
Thread.Sleep(READY_TO_FLY_BUTTON_APPEARANCE_DELAY);
|
Thread.Sleep(READY_TO_FLY_BUTTON_APPEARANCE_DELAY);
|
||||||
|
|
||||||
if (ActiveProfile.PanelSourceCoordinates.Count > 0 || ActiveProfile.TouchPanelBindings.Count > 0)
|
if (ActiveProfile.PanelSourceCoordinates.Count > 0 || ActiveProfile.TouchPanelBindings.Count > 0 || ActiveProfile.IncludeInGamePanels)
|
||||||
{
|
{
|
||||||
StatusMessageWriter.WriteMessage($"Automatic pop out is starting for profile:\n{profile.ProfileName}", StatusMessageType.Info, true);
|
StatusMessageWriter.WriteMessage($"Automatic pop out is starting for profile:\n{profile.ProfileName}", StatusMessageType.Info, true);
|
||||||
|
|
||||||
// Extra wait for cockpit view to appear and align
|
// Extra wait for cockpit view to appear and align
|
||||||
Thread.Sleep(2000);
|
Thread.Sleep(2000);
|
||||||
|
|
||||||
|
_builtInPanelConfigDelay = 4000;
|
||||||
CorePopOutSteps();
|
CorePopOutSteps();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CorePopOutSteps()
|
private void CorePopOutSteps()
|
||||||
{
|
{
|
||||||
|
// Set Windowed Display Mode window's configuration if needed
|
||||||
|
if (AppSettingData.AppSetting.AutoResizeMsfsGameWindow)
|
||||||
|
WindowActionManager.SetMsfsGameWindowLocation(ActiveProfile.MsfsGameWindowConfig);
|
||||||
|
|
||||||
// Has custom pop out panels
|
// Has custom pop out panels
|
||||||
if (ActiveProfile.PanelSourceCoordinates.Count > 0)
|
if (ActiveProfile.PanelSourceCoordinates.Count > 0)
|
||||||
{
|
{
|
||||||
|
@ -141,7 +149,7 @@ namespace MSFSPopoutPanelManager.Orchestration
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ActiveProfile.PanelSourceCoordinates.Count == 0 && ActiveProfile.TouchPanelBindings.Count == 0)
|
if (ActiveProfile.PanelSourceCoordinates.Count == 0 && ActiveProfile.TouchPanelBindings.Count == 0 && !ActiveProfile.IncludeInGamePanels)
|
||||||
{
|
{
|
||||||
StatusMessageWriter.WriteMessage("No panel has been selected for the profile. Please select at least one panel to continue.", StatusMessageType.Error, false);
|
StatusMessageWriter.WriteMessage("No panel has been selected for the profile. Please select at least one panel to continue.", StatusMessageType.Error, false);
|
||||||
return;
|
return;
|
||||||
|
@ -179,14 +187,24 @@ namespace MSFSPopoutPanelManager.Orchestration
|
||||||
// Add the MSFS Touch Panel (My other github project) windows to the panel list
|
// Add the MSFS Touch Panel (My other github project) windows to the panel list
|
||||||
if (AppSetting.TouchPanelSettings.EnableTouchPanelIntegration)
|
if (AppSetting.TouchPanelSettings.EnableTouchPanelIntegration)
|
||||||
{
|
{
|
||||||
var panelResults = AddMsfsTouchPanels(panelConfigs.Count + 1);
|
var panelResults = AddMsfsTouchPanels(panelConfigs.Count + 100); // add a panelIndex gap
|
||||||
|
if (panelResults != null)
|
||||||
|
panelConfigs.AddRange(panelResults);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the built-in panels from toolbar menu (ie. VFR Map, Check List, Weather, etc)
|
||||||
|
if (ActiveProfile.IncludeInGamePanels)
|
||||||
|
{
|
||||||
|
// Allow delay to wait for in game built-in pop outs to appear
|
||||||
|
Thread.Sleep(_builtInPanelConfigDelay);
|
||||||
|
|
||||||
|
var panelResults = AddBuiltInPanels(panelConfigs.Count + 200); // add a panelIndex gap
|
||||||
if (panelResults != null)
|
if (panelResults != null)
|
||||||
panelConfigs.AddRange(panelResults);
|
panelConfigs.AddRange(panelResults);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (panelConfigs.Count == 0)
|
if (panelConfigs.Count == 0)
|
||||||
{
|
{
|
||||||
OnPopOutCompleted?.Invoke(this, false);
|
|
||||||
StatusMessageWriter.WriteMessage("No panels have been found. Please select at least one in-game panel.", StatusMessageType.Error, false);
|
StatusMessageWriter.WriteMessage("No panels have been found. Please select at least one in-game panel.", StatusMessageType.Error, false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -217,6 +235,13 @@ namespace MSFSPopoutPanelManager.Orchestration
|
||||||
StatusMessageWriter.WriteMessage("Panels have been popped out succesfully.", StatusMessageType.Info, true);
|
StatusMessageWriter.WriteMessage("Panels have been popped out succesfully.", StatusMessageType.Info, true);
|
||||||
OnPopOutCompleted?.Invoke(this, true);
|
OnPopOutCompleted?.Invoke(this, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!ActiveProfile.IsLocked)
|
||||||
|
ProfileData.WriteProfiles();
|
||||||
|
|
||||||
|
// For migrating existing profile, if using windows mode, save MSFS game window configuration
|
||||||
|
if (AppSettingData.AppSetting.AutoResizeMsfsGameWindow && !ActiveProfile.MsfsGameWindowConfig.IsValid)
|
||||||
|
ProfileData.SaveMsfsGameWindowConfig();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -229,18 +254,25 @@ namespace MSFSPopoutPanelManager.Orchestration
|
||||||
{
|
{
|
||||||
var x = ActiveProfile.PanelSourceCoordinates[i - 1].X;
|
var x = ActiveProfile.PanelSourceCoordinates[i - 1].X;
|
||||||
var y = ActiveProfile.PanelSourceCoordinates[i - 1].Y;
|
var y = ActiveProfile.PanelSourceCoordinates[i - 1].Y;
|
||||||
|
|
||||||
|
// show the panel source overlay for split second
|
||||||
|
Task task = new Task(() => OnPanelSourceOverlayFlashed?.Invoke(this, ActiveProfile.PanelSourceCoordinates[i - 1]));
|
||||||
|
task.RunSynchronously();
|
||||||
|
|
||||||
InputEmulationManager.PopOutPanel(x, y, AppSetting.UseLeftRightControlToPopOut);
|
InputEmulationManager.PopOutPanel(x, y, AppSetting.UseLeftRightControlToPopOut);
|
||||||
|
|
||||||
var handle = PInvoke.FindWindow("AceApp", String.Empty); // Get an AceApp window with empty title
|
// Get an AceApp window with empty title
|
||||||
|
var handle = PInvoke.FindWindow("AceApp", String.Empty);
|
||||||
|
|
||||||
// Need to move the window to upper left corner first. There is a possible bug in the game that panel pop out to full screen that prevents further clicking.
|
// Need to move the window to upper left corner first. There is a possible bug in the game that panel pop out to full screen that prevents further clicking.
|
||||||
if (handle != IntPtr.Zero)
|
if (handle != IntPtr.Zero)
|
||||||
WindowActionManager.MoveWindow(handle, 0, 0, 1000, 500);
|
WindowActionManager.MoveWindow(handle, 0, 0, 1000, 500);
|
||||||
|
|
||||||
|
// The joined panel is always the first panel that got popped out
|
||||||
if (i > 1)
|
if (i > 1)
|
||||||
SeparatePanel(panels[0].PanelHandle); // The joined panel is always the first panel that got popped out
|
SeparatePanel(panels[0].PanelHandle);
|
||||||
|
|
||||||
handle = PInvoke.FindWindow("AceApp", String.Empty); // Get an AceApp window with empty title
|
handle = PInvoke.FindWindow("AceApp", String.Empty);
|
||||||
|
|
||||||
if (handle == IntPtr.Zero && i == 1)
|
if (handle == IntPtr.Zero && i == 1)
|
||||||
{
|
{
|
||||||
|
@ -293,6 +325,35 @@ namespace MSFSPopoutPanelManager.Orchestration
|
||||||
InputEmulationManager.LeftClick(point.X, point.Y);
|
InputEmulationManager.LeftClick(point.X, point.Y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<PanelConfig> AddBuiltInPanels(int panelIndex)
|
||||||
|
{
|
||||||
|
List<PanelConfig> builtinPanels = new List<PanelConfig>();
|
||||||
|
|
||||||
|
var panelHandles = WindowActionManager.GetWindowsByPanelType(new List<PanelType>() { PanelType.BuiltInPopout });
|
||||||
|
|
||||||
|
foreach (var panelHandle in panelHandles)
|
||||||
|
{
|
||||||
|
var rectangle = WindowActionManager.GetWindowRect(panelHandle);
|
||||||
|
var clientRectangle = WindowActionManager.GetClientRect(panelHandle);
|
||||||
|
|
||||||
|
builtinPanels.Add(new PanelConfig()
|
||||||
|
{
|
||||||
|
PanelIndex = panelIndex,
|
||||||
|
PanelHandle = panelHandle,
|
||||||
|
PanelType = PanelType.BuiltInPopout,
|
||||||
|
PanelName = WindowActionManager.GetWindowCaption(panelHandle),
|
||||||
|
Top = rectangle.Top,
|
||||||
|
Left = rectangle.Left,
|
||||||
|
Width = clientRectangle.Width,
|
||||||
|
Height = clientRectangle.Height
|
||||||
|
});
|
||||||
|
|
||||||
|
panelIndex++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return builtinPanels.Count == 0 ? null : builtinPanels;
|
||||||
|
}
|
||||||
|
|
||||||
private List<PanelConfig> AddMsfsTouchPanels(int panelIndex)
|
private List<PanelConfig> AddMsfsTouchPanels(int panelIndex)
|
||||||
{
|
{
|
||||||
List<PanelConfig> touchPanels = new List<PanelConfig>();
|
List<PanelConfig> touchPanels = new List<PanelConfig>();
|
||||||
|
@ -357,7 +418,7 @@ namespace MSFSPopoutPanelManager.Orchestration
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return touchPanels;
|
return touchPanels.Count == 0 ? null : touchPanels;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void LoadAndApplyPanelConfigs(List<PanelConfig> panelResults)
|
private void LoadAndApplyPanelConfigs(List<PanelConfig> panelResults)
|
||||||
|
@ -368,7 +429,18 @@ namespace MSFSPopoutPanelManager.Orchestration
|
||||||
if (panel.PanelHandle == IntPtr.Zero)
|
if (panel.PanelHandle == IntPtr.Zero)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var savedPanelConfig = ActiveProfile.PanelConfigs.FirstOrDefault(s => s.PanelIndex == panel.PanelIndex);
|
PanelConfig savedPanelConfig = null;
|
||||||
|
|
||||||
|
if (panel.PanelType == PanelType.CustomPopout || panel.PanelType == PanelType.MSFSTouchPanel)
|
||||||
|
savedPanelConfig = ActiveProfile.PanelConfigs.FirstOrDefault(s => s.PanelIndex == panel.PanelIndex);
|
||||||
|
else if (panel.PanelType == PanelType.BuiltInPopout)
|
||||||
|
savedPanelConfig = ActiveProfile.PanelConfigs.FirstOrDefault(s => s.PanelName == panel.PanelName);
|
||||||
|
|
||||||
|
if (savedPanelConfig == null)
|
||||||
|
{
|
||||||
|
panel.PanelHandle = IntPtr.Zero;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Assign previous saved values
|
// Assign previous saved values
|
||||||
if (savedPanelConfig != null)
|
if (savedPanelConfig != null)
|
||||||
|
@ -401,6 +473,14 @@ namespace MSFSPopoutPanelManager.Orchestration
|
||||||
Thread.Sleep(1000);
|
Thread.Sleep(1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Apply window size again to overcome a bug in MSFS that when moving panel between monitors, panel automatic resize for no reason
|
||||||
|
if (panel.PanelType == PanelType.BuiltInPopout)
|
||||||
|
{
|
||||||
|
Thread.Sleep(2000); // Overcome GTN750 bug
|
||||||
|
WindowActionManager.MoveWindow(panel.PanelHandle, panel.Left, panel.Top, panel.Width, panel.Height);
|
||||||
|
Thread.Sleep(1000);
|
||||||
|
}
|
||||||
|
|
||||||
if (!panel.FullScreen)
|
if (!panel.FullScreen)
|
||||||
{
|
{
|
||||||
// Apply always on top
|
// Apply always on top
|
||||||
|
@ -428,6 +508,10 @@ namespace MSFSPopoutPanelManager.Orchestration
|
||||||
Thread.Sleep(250);
|
Thread.Sleep(250);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// If profile is locked, remove all panels without handle
|
||||||
|
if (ActiveProfile.IsLocked)
|
||||||
|
panelResults.RemoveAll(p => p.PanelHandle == IntPtr.Zero);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ReturnToAfterPopOutCameraView()
|
private void ReturnToAfterPopOutCameraView()
|
||||||
|
|
|
@ -23,7 +23,7 @@ namespace MSFSPopoutPanelManager.Orchestration
|
||||||
|
|
||||||
private AppSetting AppSetting { get { return AppSettingData == null ? null : AppSettingData.AppSetting; } }
|
private AppSetting AppSetting { get { return AppSettingData == null ? null : AppSettingData.AppSetting; } }
|
||||||
|
|
||||||
public event EventHandler<PanelSourceCoordinate> onOverlayShowed;
|
public event EventHandler<PanelSourceCoordinate> OnOverlayShowed;
|
||||||
public event EventHandler OnLastOverlayRemoved;
|
public event EventHandler OnLastOverlayRemoved;
|
||||||
public event EventHandler OnAllOverlaysRemoved;
|
public event EventHandler OnAllOverlaysRemoved;
|
||||||
public event EventHandler OnSelectionStarted;
|
public event EventHandler OnSelectionStarted;
|
||||||
|
@ -71,6 +71,11 @@ namespace MSFSPopoutPanelManager.Orchestration
|
||||||
}
|
}
|
||||||
|
|
||||||
InputEmulationManager.SaveCustomView(AppSettingData.AppSetting.AutoPanningKeyBinding);
|
InputEmulationManager.SaveCustomView(AppSettingData.AppSetting.AutoPanningKeyBinding);
|
||||||
|
|
||||||
|
// If using windows mode, save MSFS game window configuration
|
||||||
|
if (AppSettingData.AppSetting.AutoResizeMsfsGameWindow)
|
||||||
|
ProfileData.SaveMsfsGameWindowConfig();
|
||||||
|
|
||||||
StatusMessageWriter.WriteMessage("Auto Panning Camera has been saved succesfully.", StatusMessageType.Info, false);
|
StatusMessageWriter.WriteMessage("Auto Panning Camera has been saved succesfully.", StatusMessageType.Info, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,7 +105,7 @@ namespace MSFSPopoutPanelManager.Orchestration
|
||||||
ActiveProfile.PanelSourceCoordinates.Add(newCoor);
|
ActiveProfile.PanelSourceCoordinates.Add(newCoor);
|
||||||
_panelIndex++;
|
_panelIndex++;
|
||||||
|
|
||||||
onOverlayShowed?.Invoke(this, newCoor);
|
OnOverlayShowed?.Invoke(this, newCoor);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void HandleOnLastPanelSelectionRemoved(object sender, Point e)
|
public void HandleOnLastPanelSelectionRemoved(object sender, Point e)
|
||||||
|
@ -122,12 +127,16 @@ namespace MSFSPopoutPanelManager.Orchestration
|
||||||
if (ActiveProfile == null)
|
if (ActiveProfile == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// Set Windowed Display Mode window's configuration if needed
|
||||||
|
if (AppSettingData.AppSetting.AutoResizeMsfsGameWindow)
|
||||||
|
WindowActionManager.SetMsfsGameWindowLocation(ActiveProfile.MsfsGameWindowConfig);
|
||||||
|
|
||||||
// remove all existing panel overlay display
|
// remove all existing panel overlay display
|
||||||
for (var i = 0; i < ActiveProfile.PanelSourceCoordinates.Count; i++)
|
for (var i = 0; i < ActiveProfile.PanelSourceCoordinates.Count; i++)
|
||||||
OnAllOverlaysRemoved?.Invoke(this, null);
|
OnAllOverlaysRemoved?.Invoke(this, null);
|
||||||
|
|
||||||
foreach (var coor in ActiveProfile.PanelSourceCoordinates)
|
foreach (var coor in ActiveProfile.PanelSourceCoordinates)
|
||||||
onOverlayShowed?.Invoke(this, new PanelSourceCoordinate() { PanelIndex = coor.PanelIndex, X = coor.X, Y = coor.Y });
|
OnOverlayShowed?.Invoke(this, new PanelSourceCoordinate() { PanelIndex = coor.PanelIndex, X = coor.X, Y = coor.Y });
|
||||||
|
|
||||||
// Turn off TrackIR if TrackIR is started
|
// Turn off TrackIR if TrackIR is started
|
||||||
FlightSimOrchestrator.TurnOffTrackIR();
|
FlightSimOrchestrator.TurnOffTrackIR();
|
||||||
|
@ -141,7 +150,7 @@ namespace MSFSPopoutPanelManager.Orchestration
|
||||||
if (ActiveProfile == null)
|
if (ActiveProfile == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// remove all existing panel overlay display
|
// Remove all existing panel overlay display
|
||||||
for (var i = 0; i < ActiveProfile.PanelSourceCoordinates.Count; i++)
|
for (var i = 0; i < ActiveProfile.PanelSourceCoordinates.Count; i++)
|
||||||
OnAllOverlaysRemoved?.Invoke(this, null);
|
OnAllOverlaysRemoved?.Invoke(this, null);
|
||||||
|
|
||||||
|
@ -154,12 +163,16 @@ namespace MSFSPopoutPanelManager.Orchestration
|
||||||
if (ActiveProfile == null)
|
if (ActiveProfile == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
//If enable, save the current viewport into custom view by Ctrl-Alt-0
|
// If enable, save the current viewport into custom view by Ctrl-Alt-0
|
||||||
if (AppSetting.UseAutoPanning)
|
if (AppSetting.UseAutoPanning)
|
||||||
InputEmulationManager.SaveCustomView(AppSetting.AutoPanningKeyBinding);
|
InputEmulationManager.SaveCustomView(AppSetting.AutoPanningKeyBinding);
|
||||||
|
|
||||||
ProfileData.WriteProfiles();
|
ProfileData.WriteProfiles();
|
||||||
|
|
||||||
|
// If using windows mode, save MSFS game window configuration
|
||||||
|
if (AppSettingData.AppSetting.AutoResizeMsfsGameWindow)
|
||||||
|
ProfileData.SaveMsfsGameWindowConfig();
|
||||||
|
|
||||||
InputHookManager.EndHook();
|
InputHookManager.EndHook();
|
||||||
|
|
||||||
// Turn TrackIR back on
|
// Turn TrackIR back on
|
||||||
|
|
|
@ -204,5 +204,18 @@ namespace MSFSPopoutPanelManager.Orchestration
|
||||||
{
|
{
|
||||||
MigrateLiveryToAircraftBinding(FlightSimData.CurrentMsfsLiveryTitle, FlightSimData.CurrentMsfsAircraft);
|
MigrateLiveryToAircraftBinding(FlightSimData.CurrentMsfsLiveryTitle, FlightSimData.CurrentMsfsAircraft);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SaveMsfsGameWindowConfig()
|
||||||
|
{
|
||||||
|
if (ActiveProfile == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var msfsGameWindowConfig = WindowsAgent.WindowActionManager.GetMsfsGameWindowLocation();
|
||||||
|
if (msfsGameWindowConfig.IsValid)
|
||||||
|
{
|
||||||
|
ActiveProfile.MsfsGameWindowConfig = msfsGameWindowConfig;
|
||||||
|
WriteProfiles();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
155
ReactClient/public/sharedworker.js
Normal file
155
ReactClient/public/sharedworker.js
Normal file
|
@ -0,0 +1,155 @@
|
||||||
|
const SIMCONNECT_DATA_REQUEST_INTERVAL_SLOW = 5000;
|
||||||
|
|
||||||
|
var apiUrl = undefined;
|
||||||
|
var networkStatus = false;
|
||||||
|
var arduinoStatus = false;
|
||||||
|
var simConnectSystemEvent = undefined;
|
||||||
|
var simConnectData = undefined;
|
||||||
|
|
||||||
|
onconnect = (ev) => {
|
||||||
|
const [port] = ev.ports;
|
||||||
|
|
||||||
|
port.onmessage = e => {
|
||||||
|
apiUrl = e.data.apiUrl;
|
||||||
|
updateInterval = e.data.updateInterval;
|
||||||
|
|
||||||
|
setInterval(() => {
|
||||||
|
port.postMessage({
|
||||||
|
networkStatus: networkStatus,
|
||||||
|
arduinoStatus: arduinoStatus,
|
||||||
|
simConnectSystemEvent: simConnectSystemEvent,
|
||||||
|
simConnectData: simConnectData
|
||||||
|
});
|
||||||
|
}, updateInterval);
|
||||||
|
|
||||||
|
requestData(updateInterval);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
requestData = async (updateInterval) => {
|
||||||
|
try {
|
||||||
|
let response = await fetch(`${apiUrl}/getdata`).catch(() => {
|
||||||
|
throw('MSFS Touch Panel Server is unavailable.')
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response !== undefined) {
|
||||||
|
let result = await response.json();
|
||||||
|
|
||||||
|
if (result === undefined)
|
||||||
|
throw new Error('MSFS Touch Panel Server error');
|
||||||
|
|
||||||
|
|
||||||
|
networkStatus = Boolean(result.msfsStatus ?? false);
|
||||||
|
arduinoStatus = Boolean(result.arduinoStatus ?? false);
|
||||||
|
|
||||||
|
if (result.systemEvent !== null && result.systemEvent !== undefined)
|
||||||
|
simConnectSystemEvent = result.systemEvent.split('-')[0];
|
||||||
|
else
|
||||||
|
simConnectSystemEvent = null;
|
||||||
|
|
||||||
|
if (!result.msfsStatus)
|
||||||
|
throw('MSFS SimConnect is unavailable.')
|
||||||
|
|
||||||
|
var simData = JSON.parse(result.data ?? []);
|
||||||
|
|
||||||
|
if ((simData !== null && simData !== []))
|
||||||
|
simConnectData = parseRequestData(simData);
|
||||||
|
|
||||||
|
setTimeout(() => requestData(updateInterval), updateInterval);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw('Empty MSFS Touch Panel Server response.')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
networkStatus = false;
|
||||||
|
setTimeout(() => requestData(SIMCONNECT_DATA_REQUEST_INTERVAL_SLOW), SIMCONNECT_DATA_REQUEST_INTERVAL_SLOW);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
parseRequestData = (resultData) => {
|
||||||
|
if (resultData === []) return [];
|
||||||
|
|
||||||
|
let newData = [];
|
||||||
|
|
||||||
|
// Format value as specified by the data key as needed and apply defaults
|
||||||
|
resultData.forEach(item => {
|
||||||
|
if (item.javaScriptFormatting !== null) {
|
||||||
|
item.value = formattingMethod[item.javaScriptFormatting](item.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item.value === null || item.value === undefined) {
|
||||||
|
item.value = item.defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
newData[item.propName] = item.value;
|
||||||
|
})
|
||||||
|
|
||||||
|
return newData;
|
||||||
|
}
|
||||||
|
|
||||||
|
formattingMethod = {
|
||||||
|
toFixed0: (value) => {
|
||||||
|
return value.toFixed(0);
|
||||||
|
},
|
||||||
|
toFixed1: (value) => {
|
||||||
|
return value.toFixed(1);
|
||||||
|
},
|
||||||
|
toFixed2: (value) => {
|
||||||
|
return value.toFixed(2);
|
||||||
|
},
|
||||||
|
toFixed3: (value) => {
|
||||||
|
return value.toFixed(3);
|
||||||
|
},
|
||||||
|
toFixed4: (value) => {
|
||||||
|
return value.toFixed(4);
|
||||||
|
},
|
||||||
|
padStartZero4: (value) => {
|
||||||
|
return String(value).padStart(4, '0');
|
||||||
|
},
|
||||||
|
decToHex: (value) => {
|
||||||
|
let str = value.toString(16);
|
||||||
|
return str.substring(0, str.length - 4).padStart(4, '0');
|
||||||
|
},
|
||||||
|
toBlankIfNegative: (value) => {
|
||||||
|
if (value < 0)
|
||||||
|
return ''
|
||||||
|
return value;
|
||||||
|
},
|
||||||
|
toBlankIfZeroOrNegative: (value) => {
|
||||||
|
if (value <= 0)
|
||||||
|
return ''
|
||||||
|
|
||||||
|
return value;
|
||||||
|
},
|
||||||
|
toBoeingFlapsValue: (value) => {
|
||||||
|
value = value.toFixed(0)
|
||||||
|
|
||||||
|
switch (value) {
|
||||||
|
case '0':
|
||||||
|
return '0';
|
||||||
|
case '1':
|
||||||
|
return '1'
|
||||||
|
case '2':
|
||||||
|
return '2'
|
||||||
|
case '3':
|
||||||
|
return '5'
|
||||||
|
case '4':
|
||||||
|
return '10'
|
||||||
|
case '5':
|
||||||
|
return '15'
|
||||||
|
case '6':
|
||||||
|
return '25'
|
||||||
|
case '7':
|
||||||
|
return '30'
|
||||||
|
case '8':
|
||||||
|
return '40'
|
||||||
|
default:
|
||||||
|
return '5'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
toBoeingElevatorTrimValue: (value) => {
|
||||||
|
return (value / 10).toFixed(2);
|
||||||
|
}
|
||||||
|
}
|
|
@ -14,20 +14,31 @@ const SimConnectDataProvider = ({ children }) => {
|
||||||
|
|
||||||
// request data from SimConnect on timer interval
|
// request data from SimConnect on timer interval
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let requestInterval = null;
|
|
||||||
|
|
||||||
let localSettings = localStorage.getItem('settings');
|
let localSettings = localStorage.getItem('settings');
|
||||||
|
let updateInterval = localSettings !== null ? JSON.parse(localSettings).dataRefreshInterval : 500;
|
||||||
|
|
||||||
|
// Using sharedworker
|
||||||
|
// sharedWorker = new SharedWorker('/sharedworker.js');
|
||||||
|
// sharedWorker.port.start();
|
||||||
|
// sharedWorker.port.postMessage({apiUrl: API_URL.url, updateInterval: updateInterval});
|
||||||
|
// sharedWorker.port.onmessage = e => {
|
||||||
|
// if(e.data !== null && e.data !== undefined)
|
||||||
|
// setArduinoStatus(Boolean(e.data.arduinoStatus));
|
||||||
|
// setNetworkStatus(Boolean(e.data.networkStatus));
|
||||||
|
|
||||||
if (localSettings !== null)
|
// if (e.data.systemEvent !== undefined && e.data.systemEvent !== null)
|
||||||
requestInterval = JSON.parse(localStorage.getItem('settings')).dataRefreshInterval;
|
// setSimConnectSystemEvent(e.data.systemEvent.split('-')[0]);
|
||||||
else
|
// else
|
||||||
requestInterval = 500;
|
// setSimConnectSystemEvent(null);
|
||||||
|
|
||||||
|
// if(e.data.simConnectData !== undefined && e.data.simConnectData !== null)
|
||||||
|
// setSimConnectData(e.data.simConnectData);
|
||||||
|
// };
|
||||||
|
|
||||||
const requestData = async () => {
|
const requestData = async () => {
|
||||||
try {
|
try {
|
||||||
let response = await fetch(`${API_URL.url}/getdata`).catch(() => {
|
let response = await fetch(`${API_URL.url}/getdata`).catch(() => {
|
||||||
handleConnectionError('MSFS Touch Panel Server is not available.')
|
throw('MSFS Touch Panel Server is not available.')
|
||||||
return;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (response !== undefined) {
|
if (response !== undefined) {
|
||||||
|
@ -36,62 +47,37 @@ const SimConnectDataProvider = ({ children }) => {
|
||||||
if (result === undefined)
|
if (result === undefined)
|
||||||
throw new Error('MSFS Touch Panel Server error');
|
throw new Error('MSFS Touch Panel Server error');
|
||||||
|
|
||||||
if (result.msfsStatus !== null && result.msfsStatus !== undefined)
|
setNetworkStatus(Boolean(result.msfsStatus ?? false));
|
||||||
setNetworkStatus(Boolean(result.msfsStatus));
|
setArduinoStatus(Boolean(result.arduinoStatus ?? false));
|
||||||
else
|
|
||||||
setNetworkStatus(false);
|
if (!result.msfsStatus)
|
||||||
|
throw('MSFS SimConnect is not available.')
|
||||||
if (result.arduinoStatus !== null && result.arduinoStatus !== undefined)
|
|
||||||
setArduinoStatus(Boolean(result.arduinoStatus));
|
|
||||||
else
|
|
||||||
setArduinoStatus(false);
|
|
||||||
|
|
||||||
if (result.systemEvent !== null && result.systemEvent !== undefined)
|
if (result.systemEvent !== null && result.systemEvent !== undefined)
|
||||||
setSimConnectSystemEvent(result.systemEvent.split('-')[0]);
|
setSimConnectSystemEvent(result.systemEvent.split('-')[0]);
|
||||||
else
|
else
|
||||||
setSimConnectSystemEvent(null);
|
setSimConnectSystemEvent(null);
|
||||||
|
|
||||||
if (!result.msfsStatus)
|
var simData = JSON.parse(result.data ?? []);
|
||||||
{
|
|
||||||
handleConnectionError('MSFS SimConnect is not available.')
|
if ((simData !== null && simData !== []))
|
||||||
return;
|
setSimConnectData(parseRequestData(simData));
|
||||||
}
|
|
||||||
|
|
||||||
if (result.data !== null && result.data !== undefined) {
|
setTimeout(() => requestData(), updateInterval);
|
||||||
var simData = JSON.parse(result.data);
|
}
|
||||||
|
else {
|
||||||
if ((simData !== null && simData !== [])) {
|
throw('Empty MSFS Touch Panel Server response.')
|
||||||
setSimConnectData(parseRequestData(simData));
|
|
||||||
clearInterval(requestInterval);
|
|
||||||
let updateInterval = JSON.parse(localStorage.getItem('settings')).dataRefreshInterval;
|
|
||||||
requestInterval = setInterval(() => requestData(), updateInterval);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
clearInterval(requestInterval);
|
|
||||||
let updateInterval = JSON.parse(localStorage.getItem('settings')).dataRefreshInterval;
|
|
||||||
requestInterval = setInterval(() => requestData(), updateInterval);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (error) {
|
catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
setNetworkStatus(false);
|
setNetworkStatus(false);
|
||||||
handleConnectionError('MSFS Touch Panel Server is not available.')
|
setTimeout(() => requestData(), SIMCONNECT_DATA_REQUEST_INTERVAL_SLOW);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleConnectionError = (errorMessage) => {
|
|
||||||
console.error(errorMessage);
|
|
||||||
clearInterval(requestInterval);
|
|
||||||
requestInterval = setInterval(() => requestData(), SIMCONNECT_DATA_REQUEST_INTERVAL_SLOW); // slow down the request data interval until network reconnection
|
|
||||||
}
|
|
||||||
|
|
||||||
requestData();
|
requestData();
|
||||||
|
|
||||||
return () => {
|
|
||||||
clearInterval(requestInterval);
|
|
||||||
}
|
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -106,7 +92,8 @@ export default SimConnectDataProvider;
|
||||||
// custom hook
|
// custom hook
|
||||||
export const useSimConnectData = () => useContext(SimConnectDataContext);
|
export const useSimConnectData = () => useContext(SimConnectDataContext);
|
||||||
|
|
||||||
export const simConnectGetPlanePanelProfilesInfo = async () => {
|
export const simConnectGetPlanePanelProfilesInfo = async () =>
|
||||||
|
{
|
||||||
try {
|
try {
|
||||||
let response = await fetch(`${API_URL.url}/getplanepanelprofileinfo`);
|
let response = await fetch(`${API_URL.url}/getplanepanelprofileinfo`);
|
||||||
let data = await response.json();
|
let data = await response.json();
|
||||||
|
|
|
@ -11,9 +11,9 @@
|
||||||
<PackageProjectUrl>https://github.com/hawkeye-stan/msfs-popout-panel-manager</PackageProjectUrl>
|
<PackageProjectUrl>https://github.com/hawkeye-stan/msfs-popout-panel-manager</PackageProjectUrl>
|
||||||
<RootNamespace>MSFSPopoutPanelManager.Shared</RootNamespace>
|
<RootNamespace>MSFSPopoutPanelManager.Shared</RootNamespace>
|
||||||
<Platforms>x64</Platforms>
|
<Platforms>x64</Platforms>
|
||||||
<Version>3.4.2.0</Version>
|
<Version>3.4.3.0</Version>
|
||||||
<AssemblyVersion>3.4.2.0</AssemblyVersion>
|
<AssemblyVersion>3.4.3.0</AssemblyVersion>
|
||||||
<FileVersion>3.4.2.0</FileVersion>
|
<FileVersion>3.4.3.0</FileVersion>
|
||||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||||
<DebugType>Embedded</DebugType>
|
<DebugType>Embedded</DebugType>
|
||||||
<Configurations>Debug;Release;DebugTouchPanel;ReleaseTouchPanel</Configurations>
|
<Configurations>Debug;Release;DebugTouchPanel;ReleaseTouchPanel</Configurations>
|
||||||
|
|
|
@ -11,9 +11,9 @@
|
||||||
<PackageProjectUrl>https://github.com/hawkeye-stan/msfs-popout-panel-manager</PackageProjectUrl>
|
<PackageProjectUrl>https://github.com/hawkeye-stan/msfs-popout-panel-manager</PackageProjectUrl>
|
||||||
<RootNamespace>MSFSPopoutPanelManager.SimConnectAgent</RootNamespace>
|
<RootNamespace>MSFSPopoutPanelManager.SimConnectAgent</RootNamespace>
|
||||||
<Platforms>x64</Platforms>
|
<Platforms>x64</Platforms>
|
||||||
<Version>3.4.2.0</Version>
|
<Version>3.4.3.0</Version>
|
||||||
<AssemblyVersion>3.4.2.0</AssemblyVersion>
|
<AssemblyVersion>3.4.3.0</AssemblyVersion>
|
||||||
<FileVersion>3.4.2.0</FileVersion>
|
<FileVersion>3.4.3.0</FileVersion>
|
||||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||||
<DebugType>Embedded</DebugType>
|
<DebugType>Embedded</DebugType>
|
||||||
<Configurations>Debug;Release;DebugTouchPanel;ReleaseTouchPanel</Configurations>
|
<Configurations>Debug;Release;DebugTouchPanel;ReleaseTouchPanel</Configurations>
|
||||||
|
|
|
@ -11,9 +11,9 @@
|
||||||
<PackageProjectUrl>https://github.com/hawkeye-stan/msfs-popout-panel-manager</PackageProjectUrl>
|
<PackageProjectUrl>https://github.com/hawkeye-stan/msfs-popout-panel-manager</PackageProjectUrl>
|
||||||
<RootNamespace>MSFSPopoutPanelManager.TouchPanelAgent</RootNamespace>
|
<RootNamespace>MSFSPopoutPanelManager.TouchPanelAgent</RootNamespace>
|
||||||
<Platforms>x64</Platforms>
|
<Platforms>x64</Platforms>
|
||||||
<Version>3.4.2.0</Version>
|
<Version>3.4.3.0</Version>
|
||||||
<AssemblyVersion>3.4.2.0</AssemblyVersion>
|
<AssemblyVersion>3.4.3.0</AssemblyVersion>
|
||||||
<FileVersion>3.4.2.0</FileVersion>
|
<FileVersion>3.4.3.0</FileVersion>
|
||||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||||
<DebugType>Embedded</DebugType>
|
<DebugType>Embedded</DebugType>
|
||||||
<Configurations>Debug;Release;DebugTouchPanel;ReleaseTouchPanel</Configurations>
|
<Configurations>Debug;Release;DebugTouchPanel;ReleaseTouchPanel</Configurations>
|
||||||
|
|
|
@ -9,21 +9,20 @@ namespace MSFSPopoutPanelManager.UserDataAgent
|
||||||
public AppSetting()
|
public AppSetting()
|
||||||
{
|
{
|
||||||
// Set defaults
|
// Set defaults
|
||||||
AutoUpdaterUrl = "https://raw.githubusercontent.com/hawkeye-stan/msfs-popout-panel-manager/master/autoupdate.xml";
|
|
||||||
LastUsedProfileId = -1;
|
LastUsedProfileId = -1;
|
||||||
MinimizeToTray = false;
|
AutoUpdaterUrl = "https://raw.githubusercontent.com/hawkeye-stan/msfs-popout-panel-manager/master/autoupdate.xml";
|
||||||
|
|
||||||
AlwaysOnTop = true;
|
AlwaysOnTop = true;
|
||||||
UseAutoPanning = true;
|
MinimizeToTray = false;
|
||||||
MinimizeAfterPopOut = false;
|
|
||||||
AutoPanningKeyBinding = "0";
|
|
||||||
StartMinimized = false;
|
StartMinimized = false;
|
||||||
AutoDisableTrackIR = true;
|
|
||||||
AutoPopOutPanels = true;
|
AutoPopOutPanels = true;
|
||||||
|
|
||||||
|
UseAutoPanning = true;
|
||||||
|
AutoPanningKeyBinding = "0";
|
||||||
|
MinimizeAfterPopOut = false;
|
||||||
OnScreenMessageDuration = 1;
|
OnScreenMessageDuration = 1;
|
||||||
UseLeftRightControlToPopOut = false;
|
UseLeftRightControlToPopOut = false;
|
||||||
IsEnabledTouchPanelServer = false;
|
|
||||||
|
|
||||||
|
|
||||||
AfterPopOutCameraView = new AfterPopOutCameraView();
|
AfterPopOutCameraView = new AfterPopOutCameraView();
|
||||||
AfterPopOutCameraView.PropertyChanged += (source, e) =>
|
AfterPopOutCameraView.PropertyChanged += (source, e) =>
|
||||||
{
|
{
|
||||||
|
@ -31,6 +30,10 @@ namespace MSFSPopoutPanelManager.UserDataAgent
|
||||||
OnPropertyChanged(arg.PropertyName, arg.OldValue, arg.NewValue);
|
OnPropertyChanged(arg.PropertyName, arg.OldValue, arg.NewValue);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
AutoDisableTrackIR = true;
|
||||||
|
|
||||||
|
AutoResizeMsfsGameWindow = true;
|
||||||
|
|
||||||
TouchScreenSettings = new TouchScreenSettings();
|
TouchScreenSettings = new TouchScreenSettings();
|
||||||
TouchScreenSettings.PropertyChanged += (source, e) =>
|
TouchScreenSettings.PropertyChanged += (source, e) =>
|
||||||
{
|
{
|
||||||
|
@ -38,6 +41,7 @@ namespace MSFSPopoutPanelManager.UserDataAgent
|
||||||
OnPropertyChanged(arg.PropertyName, arg.OldValue, arg.NewValue);
|
OnPropertyChanged(arg.PropertyName, arg.OldValue, arg.NewValue);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
IsEnabledTouchPanelServer = false;
|
||||||
TouchPanelSettings = new TouchPanelSettings();
|
TouchPanelSettings = new TouchPanelSettings();
|
||||||
TouchPanelSettings.PropertyChanged += (source, e) =>
|
TouchPanelSettings.PropertyChanged += (source, e) =>
|
||||||
{
|
{
|
||||||
|
@ -62,8 +66,6 @@ namespace MSFSPopoutPanelManager.UserDataAgent
|
||||||
|
|
||||||
public bool StartMinimized { get; set; }
|
public bool StartMinimized { get; set; }
|
||||||
|
|
||||||
public bool IncludeBuiltInPanel { get; set; }
|
|
||||||
|
|
||||||
public bool AutoPopOutPanels { get; set; }
|
public bool AutoPopOutPanels { get; set; }
|
||||||
|
|
||||||
public bool AutoDisableTrackIR { get; set; }
|
public bool AutoDisableTrackIR { get; set; }
|
||||||
|
@ -74,6 +76,8 @@ namespace MSFSPopoutPanelManager.UserDataAgent
|
||||||
|
|
||||||
public bool IsEnabledTouchPanelServer { get; set; }
|
public bool IsEnabledTouchPanelServer { get; set; }
|
||||||
|
|
||||||
|
public bool AutoResizeMsfsGameWindow { get; set; }
|
||||||
|
|
||||||
public AfterPopOutCameraView AfterPopOutCameraView { get; set; }
|
public AfterPopOutCameraView AfterPopOutCameraView { get; set; }
|
||||||
|
|
||||||
public TouchScreenSettings TouchScreenSettings { get; set; }
|
public TouchScreenSettings TouchScreenSettings { get; set; }
|
||||||
|
|
|
@ -14,6 +14,10 @@ namespace MSFSPopoutPanelManager.UserDataAgent
|
||||||
PanelSourceCoordinates = new ObservableCollection<PanelSourceCoordinate>();
|
PanelSourceCoordinates = new ObservableCollection<PanelSourceCoordinate>();
|
||||||
TouchPanelBindings = new ObservableCollection<TouchPanelBinding>();
|
TouchPanelBindings = new ObservableCollection<TouchPanelBinding>();
|
||||||
IsLocked = false;
|
IsLocked = false;
|
||||||
|
PowerOnRequiredForColdStart = false;
|
||||||
|
IncludeInGamePanels = false;
|
||||||
|
|
||||||
|
MsfsGameWindowConfig = new MsfsGameWindowConfig();
|
||||||
|
|
||||||
// Legacy data
|
// Legacy data
|
||||||
BindingAircraftLiveries = new ObservableCollection<string>();
|
BindingAircraftLiveries = new ObservableCollection<string>();
|
||||||
|
@ -40,6 +44,10 @@ namespace MSFSPopoutPanelManager.UserDataAgent
|
||||||
|
|
||||||
public bool PowerOnRequiredForColdStart { get; set; }
|
public bool PowerOnRequiredForColdStart { get; set; }
|
||||||
|
|
||||||
|
public bool IncludeInGamePanels { get; set; }
|
||||||
|
|
||||||
|
public MsfsGameWindowConfig MsfsGameWindowConfig { get; set; }
|
||||||
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public bool IsActive { get; set; }
|
public bool IsActive { get; set; }
|
||||||
|
|
||||||
|
@ -104,6 +112,9 @@ namespace MSFSPopoutPanelManager.UserDataAgent
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public bool IsCustomPopOut { get { return PanelType == PanelType.CustomPopout; } }
|
public bool IsCustomPopOut { get { return PanelType == PanelType.CustomPopout; } }
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
|
public bool IsBuiltInPopOut { get { return PanelType == PanelType.BuiltInPopout; } }
|
||||||
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public IntPtr PanelHandle { get; set; }
|
public IntPtr PanelHandle { get; set; }
|
||||||
|
|
||||||
|
@ -147,4 +158,40 @@ namespace MSFSPopoutPanelManager.UserDataAgent
|
||||||
|
|
||||||
public string PanelId { get; set; }
|
public string PanelId { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class MsfsGameWindowConfig : ObservableObject
|
||||||
|
{
|
||||||
|
public MsfsGameWindowConfig()
|
||||||
|
{
|
||||||
|
Top = 0;
|
||||||
|
Left = 0;
|
||||||
|
Width = 0;
|
||||||
|
Height = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MsfsGameWindowConfig(int left, int top, int width, int height)
|
||||||
|
{
|
||||||
|
Top = top;
|
||||||
|
Left = left;
|
||||||
|
Width = width;
|
||||||
|
Height = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Top { get; set; }
|
||||||
|
|
||||||
|
public int Left { get; set; }
|
||||||
|
|
||||||
|
public int Width { get; set; }
|
||||||
|
|
||||||
|
public int Height { get; set; }
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
|
public bool IsValid
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return Width != 0 && Height != 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,9 +10,9 @@
|
||||||
<PackageProjectUrl>https://github.com/hawkeye-stan/msfs-popout-panel-manager</PackageProjectUrl>
|
<PackageProjectUrl>https://github.com/hawkeye-stan/msfs-popout-panel-manager</PackageProjectUrl>
|
||||||
<RootNamespace>MSFSPopoutPanelManager.UserDataAgent</RootNamespace>
|
<RootNamespace>MSFSPopoutPanelManager.UserDataAgent</RootNamespace>
|
||||||
<Platforms>x64</Platforms>
|
<Platforms>x64</Platforms>
|
||||||
<Version>3.4.2.0</Version>
|
<Version>3.4.3.0</Version>
|
||||||
<AssemblyVersion>3.4.2.0</AssemblyVersion>
|
<AssemblyVersion>3.4.3.0</AssemblyVersion>
|
||||||
<FileVersion>3.4.2.0</FileVersion>
|
<FileVersion>3.4.3.0</FileVersion>
|
||||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||||
<DebugType>Embedded</DebugType>
|
<DebugType>Embedded</DebugType>
|
||||||
<Configurations>Debug;Release;DebugTouchPanel;ReleaseTouchPanel</Configurations>
|
<Configurations>Debug;Release;DebugTouchPanel;ReleaseTouchPanel</Configurations>
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
# Version History
|
# Version History
|
||||||
<hr/>
|
<hr/>
|
||||||
|
|
||||||
|
## Version 3.4.3
|
||||||
|
* Added ability to remember MSFS game window size and location for aircraft profile when running the game in windows display mode. This new setting is used to resize game window to match original size and location of MSFS game window when panel profile was defined initially. For existing aircraft profile, when running the game in windows display mode, the profile will automatically save MSFS game window position after the first successful pop out.
|
||||||
|
* Added ability to include in-game menu bar panels such as VFR Map, ATC, Checklist, etc to aircraft profile. During the pop out process, if any in-game menu bar panels are in popped out state, they will be included in panel configurations. This feature will only work if in-game menu bar panels are popped out initially and it also rely on MSFS re-opens these panels when flight starts (SU 10+).
|
||||||
|
* Added UI cue to show number circles momentarily when popping out panel to facilitate troubleshooting.
|
||||||
|
|
||||||
## Version 3.4.2
|
## Version 3.4.2
|
||||||
* Major change in how profile is bound to an aircraft. Previously, a profile is bound to an aircraft livery which requires you to activate binding when switching livery for the same aircraft. With this update, a profile is now bound to an aircraft so you no longer need to perform the binding step when switching livery. As you change active aircraft to fly, all existing livery binding will be automatically converted to aircraft binding if one exists. Also, a profile can still be bound to multiple aircrafts if you so choose such as when flying multiple variations of Cessna 172. This change has been a long awaited request to simplify your profile bindings.
|
* Major change in how profile is bound to an aircraft. Previously, a profile is bound to an aircraft livery which requires you to activate binding when switching livery for the same aircraft. With this update, a profile is now bound to an aircraft so you no longer need to perform the binding step when switching livery. As you change active aircraft to fly, all existing livery binding will be automatically converted to aircraft binding if one exists. Also, a profile can still be bound to multiple aircrafts if you so choose such as when flying multiple variations of Cessna 172. This change has been a long awaited request to simplify your profile bindings.
|
||||||
|
|
||||||
|
|
|
@ -11,9 +11,9 @@
|
||||||
<PackageProjectUrl>https://github.com/hawkeye-stan/msfs-popout-panel-manager</PackageProjectUrl>
|
<PackageProjectUrl>https://github.com/hawkeye-stan/msfs-popout-panel-manager</PackageProjectUrl>
|
||||||
<RootNamespace>MSFSPopoutPanelManager.WebServer</RootNamespace>
|
<RootNamespace>MSFSPopoutPanelManager.WebServer</RootNamespace>
|
||||||
<Platforms>x64</Platforms>
|
<Platforms>x64</Platforms>
|
||||||
<Version>3.4.2.0</Version>
|
<Version>3.4.3.0</Version>
|
||||||
<AssemblyVersion>3.4.2.0</AssemblyVersion>
|
<AssemblyVersion>3.4.3.0</AssemblyVersion>
|
||||||
<FileVersion>3.4.2.0</FileVersion>
|
<FileVersion>3.4.3.0</FileVersion>
|
||||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||||
<DebugType>Embedded</DebugType>
|
<DebugType>Embedded</DebugType>
|
||||||
<Configurations>Debug;Release;DebugTouchPanel;ReleaseTouchPanel</Configurations>
|
<Configurations>Debug;Release;DebugTouchPanel;ReleaseTouchPanel</Configurations>
|
||||||
|
|
|
@ -42,13 +42,15 @@ namespace MSFSPopoutPanelManager.WindowsAgent
|
||||||
|
|
||||||
public static void LeftClick(int x, int y)
|
public static void LeftClick(int x, int y)
|
||||||
{
|
{
|
||||||
PInvoke.SetCursorPos(x, y);
|
PInvoke.SetCursorPos(x, y); // Need to do this twice to overcome MSFS bug for separating pop out panels
|
||||||
PInvoke.SetCursorPos(x, y);
|
PInvoke.SetCursorPos(x, y);
|
||||||
Thread.Sleep(300);
|
Thread.Sleep(300);
|
||||||
|
|
||||||
PInvoke.mouse_event(MOUSEEVENTF_LEFTDOWN, x, y, 0, 0);
|
PInvoke.mouse_event(MOUSEEVENTF_LEFTDOWN, x, y, 0, 0);
|
||||||
Thread.Sleep(200);
|
Thread.Sleep(200);
|
||||||
PInvoke.mouse_event(MOUSEEVENTF_LEFTUP, x, y, 0, 0);
|
PInvoke.mouse_event(MOUSEEVENTF_LEFTUP, x, y, 0, 0);
|
||||||
|
|
||||||
|
PInvoke.SetCursorPos(x + 5, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void LeftClickFast(int x, int y)
|
public static void LeftClickFast(int x, int y)
|
||||||
|
|
|
@ -123,6 +123,9 @@ namespace MSFSPopoutPanelManager.WindowsAgent
|
||||||
[DllImport("user32.dll", CharSet = CharSet.Auto)]
|
[DllImport("user32.dll", CharSet = CharSet.Auto)]
|
||||||
public static extern IntPtr SendMessage(IntPtr hwnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
|
public static extern IntPtr SendMessage(IntPtr hwnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
|
||||||
|
|
||||||
|
[DllImport("user32.dll")]
|
||||||
|
public static extern int ShowCursor(bool bShow);
|
||||||
|
|
||||||
[DllImport("user32.dll", SetLastError = true)]
|
[DllImport("user32.dll", SetLastError = true)]
|
||||||
public static extern bool ShowWindowAsync(HandleRef hwnd, int nCmdShow);
|
public static extern bool ShowWindowAsync(HandleRef hwnd, int nCmdShow);
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using MSFSPopoutPanelManager.Shared;
|
using MSFSPopoutPanelManager.Shared;
|
||||||
|
using MSFSPopoutPanelManager.UserDataAgent;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
|
@ -98,6 +99,11 @@ namespace MSFSPopoutPanelManager.WindowsAgent
|
||||||
return PInvoke.FindWindowByCaption(IntPtr.Zero, caption);
|
return PInvoke.FindWindowByCaption(IntPtr.Zero, caption);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static string GetWindowCaption(IntPtr hwnd)
|
||||||
|
{
|
||||||
|
return PInvoke.GetWindowText(hwnd);
|
||||||
|
}
|
||||||
|
|
||||||
public static Rectangle GetClientRect(IntPtr hwnd)
|
public static Rectangle GetClientRect(IntPtr hwnd)
|
||||||
{
|
{
|
||||||
Rectangle rectangle;
|
Rectangle rectangle;
|
||||||
|
@ -136,6 +142,23 @@ namespace MSFSPopoutPanelManager.WindowsAgent
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static List<IntPtr> GetWindowsByPanelType(List<PanelType> panelTypes)
|
||||||
|
{
|
||||||
|
List<IntPtr> windowHandles = new List<IntPtr>();
|
||||||
|
|
||||||
|
PInvoke.EnumWindows((IntPtr hwnd, int lParam) =>
|
||||||
|
{
|
||||||
|
var panelType = GetWindowPanelType(hwnd);
|
||||||
|
|
||||||
|
if (panelTypes.Contains(panelType))
|
||||||
|
windowHandles.Add(hwnd);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}, 0);
|
||||||
|
|
||||||
|
return windowHandles;
|
||||||
|
}
|
||||||
|
|
||||||
public static PanelType GetWindowPanelType(IntPtr hwnd)
|
public static PanelType GetWindowPanelType(IntPtr hwnd)
|
||||||
{
|
{
|
||||||
var className = PInvoke.GetClassName(hwnd);
|
var className = PInvoke.GetClassName(hwnd);
|
||||||
|
@ -170,10 +193,70 @@ namespace MSFSPopoutPanelManager.WindowsAgent
|
||||||
var panelType = GetWindowPanelType(hwnd);
|
var panelType = GetWindowPanelType(hwnd);
|
||||||
|
|
||||||
if (panelType == PanelType.CustomPopout || panelType == PanelType.MSFSTouchPanel)
|
if (panelType == PanelType.CustomPopout || panelType == PanelType.MSFSTouchPanel)
|
||||||
WindowActionManager.CloseWindow(hwnd);
|
CloseWindow(hwnd);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}, 0);
|
}, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static MsfsGameWindowConfig GetMsfsGameWindowLocation()
|
||||||
|
{
|
||||||
|
var msfsGameWindowHandle = GetMsfsGameWindowHandle();
|
||||||
|
var isWindowedMode = IsMsfsGameInWindowedMode(msfsGameWindowHandle);
|
||||||
|
|
||||||
|
if (isWindowedMode)
|
||||||
|
{
|
||||||
|
var windowRect = GetWindowRect(msfsGameWindowHandle);
|
||||||
|
var clientRect = GetClientRect(msfsGameWindowHandle);
|
||||||
|
return new MsfsGameWindowConfig(windowRect.Left, windowRect.Top, clientRect.Width + 16, clientRect.Height + 39);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new MsfsGameWindowConfig(0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SetMsfsGameWindowLocation(MsfsGameWindowConfig msfsGameWindowConfig)
|
||||||
|
{
|
||||||
|
var msfsGameWindowHandle = GetMsfsGameWindowHandle();
|
||||||
|
var isWindowedMode = IsMsfsGameInWindowedMode(msfsGameWindowHandle);
|
||||||
|
|
||||||
|
if (isWindowedMode && msfsGameWindowConfig.IsValid)
|
||||||
|
PInvoke.MoveWindow(msfsGameWindowHandle, msfsGameWindowConfig.Left, msfsGameWindowConfig.Top, msfsGameWindowConfig.Width, msfsGameWindowConfig.Height, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool IsMsfsGameInWindowedMode(IntPtr msfsGameWindowHandle)
|
||||||
|
{
|
||||||
|
if (msfsGameWindowHandle != IntPtr.Zero)
|
||||||
|
{
|
||||||
|
var currentStyle = (uint)PInvoke.GetWindowLong(msfsGameWindowHandle, PInvokeConstant.GWL_STYLE);
|
||||||
|
return (currentStyle & PInvokeConstant.WS_CAPTION) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IntPtr GetMsfsGameWindowHandle()
|
||||||
|
{
|
||||||
|
IntPtr msfsGameWindowHandle = IntPtr.Zero;
|
||||||
|
|
||||||
|
// Get game window handle
|
||||||
|
PInvoke.EnumWindows(new PInvoke.CallBack((IntPtr hwnd, int lParam) =>
|
||||||
|
{
|
||||||
|
var className = PInvoke.GetClassName(hwnd);
|
||||||
|
|
||||||
|
if (className == "AceApp") // MSFS windows designation
|
||||||
|
{
|
||||||
|
var caption = WindowsAgent.PInvoke.GetWindowText(hwnd);
|
||||||
|
|
||||||
|
if (caption.IndexOf("Microsoft Flight Simulator") > -1) // MSFS main game window
|
||||||
|
{
|
||||||
|
msfsGameWindowHandle = hwnd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}), 0);
|
||||||
|
|
||||||
|
return msfsGameWindowHandle;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,9 +11,9 @@
|
||||||
<PackageProjectUrl>https://github.com/hawkeye-stan/msfs-popout-panel-manager</PackageProjectUrl>
|
<PackageProjectUrl>https://github.com/hawkeye-stan/msfs-popout-panel-manager</PackageProjectUrl>
|
||||||
<RootNamespace>MSFSPopoutPanelManager.WindowsAgent</RootNamespace>
|
<RootNamespace>MSFSPopoutPanelManager.WindowsAgent</RootNamespace>
|
||||||
<Platforms>x64</Platforms>
|
<Platforms>x64</Platforms>
|
||||||
<Version>3.4.2.0</Version>
|
<Version>3.4.3.0</Version>
|
||||||
<AssemblyVersion>3.4.2.0</AssemblyVersion>
|
<AssemblyVersion>3.4.3.0</AssemblyVersion>
|
||||||
<FileVersion>3.4.2.0</FileVersion>
|
<FileVersion>3.4.3.0</FileVersion>
|
||||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||||
<DebugType>Embedded</DebugType>
|
<DebugType>Embedded</DebugType>
|
||||||
<Configurations>Debug;Release;DebugTouchPanel;ReleaseTouchPanel</Configurations>
|
<Configurations>Debug;Release;DebugTouchPanel;ReleaseTouchPanel</Configurations>
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
xmlns:shared="clr-namespace:MSFSPopoutPanelManager.Shared;assembly=Shared"
|
xmlns:shared="clr-namespace:MSFSPopoutPanelManager.Shared;assembly=Shared"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
Title="MSFS Pop Out Panel Manager"
|
Title="MSFS Pop Out Panel Manager"
|
||||||
Height="710"
|
Height="740"
|
||||||
Width="920"
|
Width="920"
|
||||||
WindowStartupLocation="CenterScreen"
|
WindowStartupLocation="CenterScreen"
|
||||||
ResizeMode="CanMinimize"
|
ResizeMode="CanMinimize"
|
||||||
|
@ -72,7 +72,7 @@
|
||||||
</Image>
|
</Image>
|
||||||
</DockPanel>
|
</DockPanel>
|
||||||
<DockPanel>
|
<DockPanel>
|
||||||
<StackPanel Name="panelSteps" DockPanel.Dock="Top" Height="545" Background="#FF323C64">
|
<StackPanel Name="panelSteps" DockPanel.Dock="Top" Height="575" Background="#FF323C64">
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
<WrapPanel DockPanel.Dock="Top" Orientation="Horizontal" Height="70" Background="#FF252523">
|
<WrapPanel DockPanel.Dock="Top" Orientation="Horizontal" Height="70" Background="#FF252523">
|
||||||
<Label Content="Status" Margin="5, 10, 5, 5"/>
|
<Label Content="Status" Margin="5, 10, 5, 5"/>
|
||||||
|
|
|
@ -10,6 +10,7 @@ namespace MSFSPopoutPanelManager.WpfApp
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
this.Title = title;
|
this.Title = title;
|
||||||
this.txtMessage.Text = message;
|
this.txtMessage.Text = message;
|
||||||
|
this.Topmost = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void btnDialogYes_Click(object sender, RoutedEventArgs e)
|
private void btnDialogYes_Click(object sender, RoutedEventArgs e)
|
||||||
|
|
|
@ -7,15 +7,15 @@
|
||||||
Title="PanelCoorOverlay"
|
Title="PanelCoorOverlay"
|
||||||
ResizeMode="NoResize"
|
ResizeMode="NoResize"
|
||||||
WindowStyle="None"
|
WindowStyle="None"
|
||||||
Height="46"
|
Height="30"
|
||||||
Width="55"
|
Width="30"
|
||||||
SizeToContent="WidthAndHeight"
|
SizeToContent="WidthAndHeight"
|
||||||
Background="#01F0F0FF"
|
Background="#01F0F0FF"
|
||||||
AllowsTransparency="True"
|
AllowsTransparency="True"
|
||||||
MouseMove="Window_MouseMove"
|
MouseMove="Window_MouseMove"
|
||||||
Loaded="Window_Loaded">
|
Loaded="Window_Loaded">
|
||||||
<Grid>
|
<Grid>
|
||||||
<Label Name="lblPanelIndex" Content="1" HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
<Label Name="lblPanelIndex" Content="1" HorizontalAlignment="Center" VerticalAlignment="Center" Padding="0,0,0,2"/>
|
||||||
<Image Height="46" Width="55" HorizontalAlignment="Left" VerticalAlignment="Top" Opacity="1" Source="resources/transparent.png"/>
|
<Image Height="30" Width="30" HorizontalAlignment="Left" VerticalAlignment="Top" Opacity="1" Source="resources/transparent.png"/>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Window>
|
</Window>
|
||||||
|
|
|
@ -8,8 +8,8 @@ namespace MSFSPopoutPanelManager.WpfApp
|
||||||
{
|
{
|
||||||
public partial class PanelCoorOverlay : Window
|
public partial class PanelCoorOverlay : Window
|
||||||
{
|
{
|
||||||
private const int TOP_ADJUSTMENT = 23; // half of window height
|
private const int TOP_ADJUSTMENT = 15; // half of window height
|
||||||
private const int LEFT_ADJUSTMENT = 27; // half of window width
|
private const int LEFT_ADJUSTMENT = 15; // half of window width
|
||||||
private int _xCoor;
|
private int _xCoor;
|
||||||
private int _yCoor;
|
private int _yCoor;
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,7 @@
|
||||||
</Window.Resources>
|
</Window.Resources>
|
||||||
<Grid>
|
<Grid>
|
||||||
<DockPanel>
|
<DockPanel>
|
||||||
<TreeView Width="250" VerticalAlignment="Stretch" DockPanel.Dock="Left">
|
<TreeView Width="240" VerticalAlignment="Stretch" DockPanel.Dock="Left">
|
||||||
<TreeView.ItemContainerStyle>
|
<TreeView.ItemContainerStyle>
|
||||||
<Style TargetType="{x:Type TreeViewItem}">
|
<Style TargetType="{x:Type TreeViewItem}">
|
||||||
<Setter Property="IsExpanded" Value="True" />
|
<Setter Property="IsExpanded" Value="True" />
|
||||||
|
@ -58,11 +58,12 @@
|
||||||
</Style.Resources>
|
</Style.Resources>
|
||||||
</Style>
|
</Style>
|
||||||
</TreeView.ItemContainerStyle>
|
</TreeView.ItemContainerStyle>
|
||||||
<TreeViewItem Header="Application Settings" Selected="TreeViewItem_Selected" Margin="0,15,0,10" IsSelected="True"></TreeViewItem>
|
<TreeViewItem Header="Application Settings" Selected="TreeViewItem_Selected" Margin="0,15,0,10" IsSelected="True" Padding="0"></TreeViewItem>
|
||||||
<TreeViewItem Header="Pop Out Settings" Selected="TreeViewItem_Selected" Margin="0,0,0,10"></TreeViewItem>
|
|
||||||
<TreeViewItem Header="Auto Pop Out Panel Settings" Selected="TreeViewItem_Selected" Margin="0,0,0,10"></TreeViewItem>
|
<TreeViewItem Header="Auto Pop Out Panel Settings" Selected="TreeViewItem_Selected" Margin="0,0,0,10"></TreeViewItem>
|
||||||
<TreeViewItem Header="Track IR Settings" Selected="TreeViewItem_Selected" Margin="0,0,0,10"></TreeViewItem>
|
<TreeViewItem Header="Pop Out Settings" Selected="TreeViewItem_Selected" Margin="0,0,0,10"></TreeViewItem>
|
||||||
<TreeViewItem Header="Touch Settings" Selected="TreeViewItem_Selected" Margin="0,0,0,10"></TreeViewItem>
|
<TreeViewItem Header="Touch Settings" Selected="TreeViewItem_Selected" Margin="0,0,0,10"></TreeViewItem>
|
||||||
|
<TreeViewItem Header="Track IR Settings" Selected="TreeViewItem_Selected" Margin="0,0,0,10"></TreeViewItem>
|
||||||
|
<TreeViewItem Header="Windowed Mode Settings" Selected="TreeViewItem_Selected" Margin="0,0,0,10"></TreeViewItem>
|
||||||
<TreeViewItem Header="MSFS Touch Panel Settings" Selected="TreeViewItem_Selected" Margin="0,0,0,10" Visibility="{Binding Path=AppSettingData.AppSetting.IsEnabledTouchPanelServer, Converter={StaticResource VisibleIfTrueConverter}, Mode=OneWay}"></TreeViewItem>
|
<TreeViewItem Header="MSFS Touch Panel Settings" Selected="TreeViewItem_Selected" Margin="0,0,0,10" Visibility="{Binding Path=AppSettingData.AppSetting.IsEnabledTouchPanelServer, Converter={StaticResource VisibleIfTrueConverter}, Mode=OneWay}"></TreeViewItem>
|
||||||
</TreeView>
|
</TreeView>
|
||||||
<WrapPanel DockPanel.Dock="Right" Margin="20,10,0,0">
|
<WrapPanel DockPanel.Dock="Right" Margin="20,10,0,0">
|
||||||
|
@ -96,6 +97,23 @@
|
||||||
<AccessText TextWrapping="Wrap">Start the application in minimized mode in system tray.</AccessText>
|
<AccessText TextWrapping="Wrap">Start the application in minimized mode in system tray.</AccessText>
|
||||||
</CheckBox>
|
</CheckBox>
|
||||||
</WrapPanel>
|
</WrapPanel>
|
||||||
|
|
||||||
|
</WrapPanel>
|
||||||
|
</ScrollViewer>
|
||||||
|
<ScrollViewer VerticalScrollBarVisibility="Auto">
|
||||||
|
<WrapPanel Orientation="Vertical" Visibility="{Binding WindowedModeSettingsVisible, Converter={StaticResource VisibleIfTrueConverter}, Mode=OneWay}">
|
||||||
|
<WrapPanel Orientation="Vertical" Margin="0,0,20,20">
|
||||||
|
<TextBlock Style="{StaticResource TextBlockHeading}">Auto Resize MSFS Game Window (Used with Windowed Display Mode only)</TextBlock>
|
||||||
|
<Line Stretch="Fill" Stroke="Gray" X2="1"/>
|
||||||
|
<CheckBox IsChecked="{Binding AppSettingData.AppSetting.AutoResizeMsfsGameWindow, Mode=TwoWay}" >
|
||||||
|
<AccessText TextWrapping="Wrap">Enable automatic resize of MSFS game window when using Windowed Display Mode. When playing the game in Windowed Display Mode, this setting is used to resize game window to match original size
|
||||||
|
and location when panel profile was initially defined. When this setting is first checked, current game window size and location will also be saved automatically.</AccessText>
|
||||||
|
</CheckBox>
|
||||||
|
<TextBlock TextWrapping="Wrap" Margin="28,10,0,0" FontSize="14">
|
||||||
|
To override previously saved MSFS game window size and location, when editing panel location overlay, please also click Override Auto Panning Camera. This will not only save updated panel locations, it will also save MSFS
|
||||||
|
game window size and location to be used on subsequent pop out.
|
||||||
|
</TextBlock>
|
||||||
|
</WrapPanel>
|
||||||
</WrapPanel>
|
</WrapPanel>
|
||||||
</ScrollViewer>
|
</ScrollViewer>
|
||||||
<ScrollViewer VerticalScrollBarVisibility="Auto">
|
<ScrollViewer VerticalScrollBarVisibility="Auto">
|
||||||
|
@ -282,7 +300,7 @@
|
||||||
</WrapPanel>
|
</WrapPanel>
|
||||||
<WrapPanel Visibility="{Binding AppSettingData.AppSetting.TouchPanelSettings.EnableTouchPanelIntegration, Converter={StaticResource VisibleIfTrueConverter}, Mode=OneWay}">
|
<WrapPanel Visibility="{Binding AppSettingData.AppSetting.TouchPanelSettings.EnableTouchPanelIntegration, Converter={StaticResource VisibleIfTrueConverter}, Mode=OneWay}">
|
||||||
<TextBlock FontStyle="Italic">
|
<TextBlock FontStyle="Italic">
|
||||||
Restart is require for all changes below to take effect.
|
Restart is required for all changes below to take effect.
|
||||||
</TextBlock>
|
</TextBlock>
|
||||||
<WrapPanel Orientation="Vertical" Margin="0,0,20,20">
|
<WrapPanel Orientation="Vertical" Margin="0,0,20,20">
|
||||||
<TextBlock Style="{StaticResource TextBlockHeading}">Enable Use of Arduino</TextBlock>
|
<TextBlock Style="{StaticResource TextBlockHeading}">Enable Use of Arduino</TextBlock>
|
||||||
|
|
|
@ -16,6 +16,8 @@ namespace MSFSPopoutPanelManager.WpfApp
|
||||||
|
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
this.DataContext = preferencesViewModel;
|
this.DataContext = preferencesViewModel;
|
||||||
|
|
||||||
|
_preferencesViewModel.Window = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public AppSetting AppSetting { get; set; }
|
public AppSetting AppSetting { get; set; }
|
||||||
|
@ -32,6 +34,8 @@ namespace MSFSPopoutPanelManager.WpfApp
|
||||||
|
|
||||||
public bool MSFSTouchPanelSettingsVisible { get; set; }
|
public bool MSFSTouchPanelSettingsVisible { get; set; }
|
||||||
|
|
||||||
|
public bool WindowModeSettingsVisible { get; set; }
|
||||||
|
|
||||||
private void TreeViewItem_Selected(object sender, RoutedEventArgs e)
|
private void TreeViewItem_Selected(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
var treeViewItem = (TreeViewItem)e.Source;
|
var treeViewItem = (TreeViewItem)e.Source;
|
||||||
|
|
|
@ -3,7 +3,8 @@
|
||||||
"WpfApp": {
|
"WpfApp": {
|
||||||
"commandName": "Project",
|
"commandName": "Project",
|
||||||
"environmentVariables": {
|
"environmentVariables": {
|
||||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
"ASPNETCORE_ENVIRONMENT": "Development",
|
||||||
|
"ENABLE_XAML_DIAGNOSTICS_SOURCE_INFO": "1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.6 KiB |
|
@ -16,6 +16,6 @@
|
||||||
<SolidColorBrush Color="#FFF0F0F0" Opacity="0.01" />
|
<SolidColorBrush Color="#FFF0F0F0" Opacity="0.01" />
|
||||||
</Window.Background>
|
</Window.Background>
|
||||||
<Grid>
|
<Grid>
|
||||||
<wv2:WebView2 Name="webView" DefaultBackgroundColor="Transparent" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
|
<wv2:WebView2 Name="webView" DefaultBackgroundColor="Transparent" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Source=""/>
|
||||||
</Grid>
|
</Grid>
|
||||||
</mah:MetroWindow>
|
</mah:MetroWindow>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
using MahApps.Metro.Controls;
|
using MahApps.Metro.Controls;
|
||||||
using Microsoft.Web.WebView2.Wpf;
|
using Microsoft.Web.WebView2.Core;
|
||||||
using MSFSPopoutPanelManager.Shared;
|
using MSFSPopoutPanelManager.Shared;
|
||||||
using System;
|
using System;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
@ -11,8 +11,9 @@ namespace MSFSPopoutPanelManager.WpfApp
|
||||||
{
|
{
|
||||||
private string _planeId;
|
private string _planeId;
|
||||||
private string _panelId;
|
private string _panelId;
|
||||||
|
private CoreWebView2Environment _webView2Environment;
|
||||||
|
|
||||||
public TouchPanelWebViewDialog(string planeId, string panelId, string caption, int width, int height)
|
public TouchPanelWebViewDialog(string planeId, string panelId, string caption, int width, int height, CoreWebView2Environment environment)
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
//this.Topmost = true;
|
//this.Topmost = true;
|
||||||
|
@ -22,23 +23,24 @@ namespace MSFSPopoutPanelManager.WpfApp
|
||||||
|
|
||||||
_planeId = planeId;
|
_planeId = planeId;
|
||||||
_panelId = panelId;
|
_panelId = panelId;
|
||||||
|
_webView2Environment = environment;
|
||||||
|
|
||||||
Loaded += TouchPanelWebViewDialog_Loaded;
|
Loaded += TouchPanelWebViewDialog_Loaded;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void TouchPanelWebViewDialog_Loaded(object sender, System.Windows.RoutedEventArgs e)
|
private async void TouchPanelWebViewDialog_Loaded(object sender, System.Windows.RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
StartWebView(webView);
|
await webView.EnsureCoreWebView2Async(_webView2Environment);
|
||||||
|
|
||||||
// This somehow fixes webview did not maximize correctly when the host WPF dialog is maximized
|
if (webView != null && webView.CoreWebView2 != null)
|
||||||
|
{
|
||||||
|
webView.CoreWebView2.Navigate($"{Constants.WEB_HOST_URI}/{_planeId.ToLower()}/{_panelId.ToLower()}");
|
||||||
|
}
|
||||||
|
|
||||||
|
// This fixes webview which does not maximize correctly when host WPF dialog is maximized
|
||||||
WindowExtensions.FixWindowMaximizeCropping(this);
|
WindowExtensions.FixWindowMaximizeCropping(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void StartWebView(WebView2 webView)
|
|
||||||
{
|
|
||||||
webView.Source = new Uri($"{Constants.WEB_HOST_URI}/{_planeId.ToLower()}/{_panelId.ToLower()}");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
|
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
|
||||||
{
|
{
|
||||||
webView.Dispose();
|
webView.Dispose();
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
xmlns:c="clr-namespace:CalcBinding;assembly=CalcBinding"
|
xmlns:c="clr-namespace:CalcBinding;assembly=CalcBinding"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
Height="545"
|
Height="575"
|
||||||
Width="920"
|
Width="920"
|
||||||
Background="#FF323A64">
|
Background="#FF323A64">
|
||||||
<UserControl.Resources>
|
<UserControl.Resources>
|
||||||
|
@ -45,7 +45,7 @@
|
||||||
<Image Width="22" Height="22" VerticalAlignment="Center" Source="Resources\info_icon.png"></Image>
|
<Image Width="22" Height="22" VerticalAlignment="Center" Source="Resources\info_icon.png"></Image>
|
||||||
</controls:Tile>
|
</controls:Tile>
|
||||||
</WrapPanel>
|
</WrapPanel>
|
||||||
<DataGrid Name="PanelConfigGrid" HorizontalAlignment="Center" Width="882" Height="430" Margin="0 10 0 0" AutoGenerateColumns="False" CanUserResizeColumns="False" HorizontalScrollBarVisibility="Disabled"
|
<DataGrid Name="PanelConfigGrid" HorizontalAlignment="Center" Width="882" Height="460" Margin="0 10 0 0" AutoGenerateColumns="False" CanUserResizeColumns="False" HorizontalScrollBarVisibility="Disabled"
|
||||||
CanUserReorderColumns="False" CanUserResizeRows="False" HorizontalGridLinesBrush="#B9B9B9" VerticalGridLinesBrush="#B9B9B9" GridLinesVisibility="Horizontal" SelectionUnit="Cell"
|
CanUserReorderColumns="False" CanUserResizeRows="False" HorizontalGridLinesBrush="#B9B9B9" VerticalGridLinesBrush="#B9B9B9" GridLinesVisibility="Horizontal" SelectionUnit="Cell"
|
||||||
BorderThickness="1" CanUserAddRows="False" CanUserSortColumns="False" KeyboardNavigation.TabNavigation="None" KeyboardNavigation.IsTabStop="False"
|
BorderThickness="1" CanUserAddRows="False" CanUserSortColumns="False" KeyboardNavigation.TabNavigation="None" KeyboardNavigation.IsTabStop="False"
|
||||||
ItemsSource="{Binding ProfileData.ActiveProfile.PanelConfigs}" HeadersVisibility="Column" KeyboardNavigation.DirectionalNavigation="Local" MouseDown="PanelConfigGrid_MouseDown">
|
ItemsSource="{Binding ProfileData.ActiveProfile.PanelConfigs}" HeadersVisibility="Column" KeyboardNavigation.DirectionalNavigation="Local" MouseDown="PanelConfigGrid_MouseDown">
|
||||||
|
@ -211,7 +211,7 @@
|
||||||
SourceUpdated="GridData_SourceUpdated"
|
SourceUpdated="GridData_SourceUpdated"
|
||||||
IsChecked="{Binding HideTitlebar, Mode=TwoWay, NotifyOnSourceUpdated=True, UpdateSourceTrigger=PropertyChanged}"
|
IsChecked="{Binding HideTitlebar, Mode=TwoWay, NotifyOnSourceUpdated=True, UpdateSourceTrigger=PropertyChanged}"
|
||||||
IsEnabled="{c:Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid, AncestorLevel=1}, Path='!DataContext.ProfileData.ActiveProfile.IsLocked '}"
|
IsEnabled="{c:Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid, AncestorLevel=1}, Path='!DataContext.ProfileData.ActiveProfile.IsLocked '}"
|
||||||
IsHitTestVisible="{c:Binding Path='!FullScreen and IsCustomPopOut'}"/>
|
IsHitTestVisible="{c:Binding Path='!FullScreen and (IsCustomPopOut or IsBuiltInPopOut)'}"/>
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
</DataGridTemplateColumn.CellTemplate>
|
</DataGridTemplateColumn.CellTemplate>
|
||||||
</DataGridTemplateColumn>
|
</DataGridTemplateColumn>
|
||||||
|
@ -222,7 +222,7 @@
|
||||||
SourceUpdated="GridData_SourceUpdated"
|
SourceUpdated="GridData_SourceUpdated"
|
||||||
IsChecked="{Binding FullScreen, Mode=TwoWay, NotifyOnSourceUpdated=True, UpdateSourceTrigger=PropertyChanged}"
|
IsChecked="{Binding FullScreen, Mode=TwoWay, NotifyOnSourceUpdated=True, UpdateSourceTrigger=PropertyChanged}"
|
||||||
IsEnabled="{c:Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid, AncestorLevel=1}, Path='!DataContext.ProfileData.ActiveProfile.IsLocked'}"
|
IsEnabled="{c:Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid, AncestorLevel=1}, Path='!DataContext.ProfileData.ActiveProfile.IsLocked'}"
|
||||||
IsHitTestVisible="{c:Binding Path='IsCustomPopOut'}"/>
|
IsHitTestVisible="{c:Binding Path='IsCustomPopOut or IsBuiltInPopOut'}"/>
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
</DataGridTemplateColumn.CellTemplate>
|
</DataGridTemplateColumn.CellTemplate>
|
||||||
</DataGridTemplateColumn>
|
</DataGridTemplateColumn>
|
||||||
|
@ -233,7 +233,7 @@
|
||||||
SourceUpdated="GridData_SourceUpdated"
|
SourceUpdated="GridData_SourceUpdated"
|
||||||
IsChecked="{Binding TouchEnabled, Mode=TwoWay, NotifyOnSourceUpdated=True, UpdateSourceTrigger=PropertyChanged}"
|
IsChecked="{Binding TouchEnabled, Mode=TwoWay, NotifyOnSourceUpdated=True, UpdateSourceTrigger=PropertyChanged}"
|
||||||
IsEnabled="{c:Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid, AncestorLevel=1}, Path='!DataContext.ProfileData.ActiveProfile.IsLocked'}"
|
IsEnabled="{c:Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid, AncestorLevel=1}, Path='!DataContext.ProfileData.ActiveProfile.IsLocked'}"
|
||||||
IsHitTestVisible="{c:Binding Path='!FullScreen and IsCustomPopOut'}"/>
|
IsHitTestVisible="{c:Binding Path='!FullScreen and (IsCustomPopOut or IsBuiltInPopOut)'}"/>
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
</DataGridTemplateColumn.CellTemplate>
|
</DataGridTemplateColumn.CellTemplate>
|
||||||
</DataGridTemplateColumn>
|
</DataGridTemplateColumn>
|
||||||
|
@ -244,7 +244,7 @@
|
||||||
SourceUpdated="GridData_SourceUpdated"
|
SourceUpdated="GridData_SourceUpdated"
|
||||||
IsChecked="{Binding DisableGameRefocus, Mode=TwoWay, NotifyOnSourceUpdated=True, UpdateSourceTrigger=PropertyChanged}"
|
IsChecked="{Binding DisableGameRefocus, Mode=TwoWay, NotifyOnSourceUpdated=True, UpdateSourceTrigger=PropertyChanged}"
|
||||||
IsEnabled="{c:Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid, AncestorLevel=1}, Path='!DataContext.ProfileData.ActiveProfile.IsLocked'}"
|
IsEnabled="{c:Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid, AncestorLevel=1}, Path='!DataContext.ProfileData.ActiveProfile.IsLocked'}"
|
||||||
IsHitTestVisible="{c:Binding Path='!FullScreen and IsCustomPopOut and TouchEnabled'}"/>
|
IsHitTestVisible="{c:Binding Path='!FullScreen and (IsCustomPopOut or IsBuiltInPopOut) and TouchEnabled'}"/>
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
</DataGridTemplateColumn.CellTemplate>
|
</DataGridTemplateColumn.CellTemplate>
|
||||||
</DataGridTemplateColumn>
|
</DataGridTemplateColumn>
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase"
|
xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase"
|
||||||
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
|
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
Height="545"
|
Height="575"
|
||||||
Width="920"
|
Width="920"
|
||||||
Background="#FF323A64">
|
Background="#FF323A64">
|
||||||
<UserControl.Resources>
|
<UserControl.Resources>
|
||||||
|
@ -77,6 +77,7 @@
|
||||||
<Button Content="-" ToolTip="Delete Binding" Margin="10,0,0,0" Width="40" Command="{Binding DeleteProfileBindingCommand}"/>
|
<Button Content="-" ToolTip="Delete Binding" Margin="10,0,0,0" Width="40" Command="{Binding DeleteProfileBindingCommand}"/>
|
||||||
</WrapPanel>
|
</WrapPanel>
|
||||||
<CheckBox Margin="10,5,0,0" Content="Power on required to pop out panels on cold start (G1000 / NXi Only)" IsChecked="{Binding ProfileData.ActiveProfile.PowerOnRequiredForColdStart}" Command="{Binding SetPowerOnRequiredCommand}" />
|
<CheckBox Margin="10,5,0,0" Content="Power on required to pop out panels on cold start (G1000 / NXi Only)" IsChecked="{Binding ProfileData.ActiveProfile.PowerOnRequiredForColdStart}" Command="{Binding SetPowerOnRequiredCommand}" />
|
||||||
|
<CheckBox Margin="10,5,0,0" Content="Include in-game menu bar panels (VFR Map, Checklist, ATC, etc)" IsChecked="{Binding ProfileData.ActiveProfile.IncludeInGamePanels}" Command="{Binding SetIncludeInGamePanelsCommand}" />
|
||||||
<WrapPanel Name="TouchPanelConfigurationPanel" Orientation="Horizontal" Margin="0,10,0,0" Visibility="{Binding AppSettingData.AppSetting.IsEnabledTouchPanelServer, Converter={StaticResource VisibleIfTrueConverter}, Mode=OneWay}" >
|
<WrapPanel Name="TouchPanelConfigurationPanel" Orientation="Horizontal" Margin="0,10,0,0" Visibility="{Binding AppSettingData.AppSetting.IsEnabledTouchPanelServer, Converter={StaticResource VisibleIfTrueConverter}, Mode=OneWay}" >
|
||||||
<Label Content="Open MSFS touch panel when flight session starts" Margin="5,0,0,0" />
|
<Label Content="Open MSFS touch panel when flight session starts" Margin="5,0,0,0" />
|
||||||
<Button Content="+" ToolTip="Add Binding" Margin="94,0,0,0" Width="40" Command="{Binding OpenTouchPanelBindingCommand}"/>
|
<Button Content="+" ToolTip="Add Binding" Margin="94,0,0,0" Width="40" Command="{Binding OpenTouchPanelBindingCommand}"/>
|
||||||
|
@ -114,7 +115,7 @@
|
||||||
</WrapPanel>
|
</WrapPanel>
|
||||||
<DockPanel DockPanel.Dock="Right" Width="325" HorizontalAlignment="Center">
|
<DockPanel DockPanel.Dock="Right" Width="325" HorizontalAlignment="Center">
|
||||||
<Label DockPanel.Dock="Top" Content="Panel Locations" HorizontalAlignment="Center" Margin="0,10,0,0"/>
|
<Label DockPanel.Dock="Top" Content="Panel Locations" HorizontalAlignment="Center" Margin="0,10,0,0"/>
|
||||||
<DataGrid DockPanel.Dock="Top" HorizontalAlignment="Center" Width="290" Height="435" AutoGenerateColumns="False" CanUserResizeColumns="False" HorizontalScrollBarVisibility="Disabled"
|
<DataGrid DockPanel.Dock="Top" HorizontalAlignment="Center" Width="290" Height="465" AutoGenerateColumns="False" CanUserResizeColumns="False" HorizontalScrollBarVisibility="Disabled"
|
||||||
CanUserReorderColumns="False" CanUserResizeRows="False" IsReadOnly="True" HorizontalGridLinesBrush="#B9B9B9" VerticalGridLinesBrush="#B9B9B9" GridLinesVisibility="Horizontal" BorderThickness="1"
|
CanUserReorderColumns="False" CanUserResizeRows="False" IsReadOnly="True" HorizontalGridLinesBrush="#B9B9B9" VerticalGridLinesBrush="#B9B9B9" GridLinesVisibility="Horizontal" BorderThickness="1"
|
||||||
CanUserAddRows="False" CanUserSortColumns="False" ItemsSource="{Binding ProfileData.ActiveProfile.PanelSourceCoordinates}">
|
CanUserAddRows="False" CanUserSortColumns="False" ItemsSource="{Binding ProfileData.ActiveProfile.PanelSourceCoordinates}">
|
||||||
<DataGrid.CellStyle>
|
<DataGrid.CellStyle>
|
||||||
|
|
|
@ -16,6 +16,16 @@ namespace MSFSPopoutPanelManager.WpfApp.ViewModel
|
||||||
return (bool)dialog.ShowDialog();
|
return (bool)dialog.ShowDialog();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static bool ConfirmDialog(string title, string message, Window owner)
|
||||||
|
{
|
||||||
|
var dialog = new ConfirmationDialog(title, message);
|
||||||
|
dialog.Owner = owner;
|
||||||
|
dialog.Topmost = true;
|
||||||
|
dialog.WindowStartupLocation = WindowStartupLocation.CenterOwner;
|
||||||
|
|
||||||
|
return (bool)dialog.ShowDialog();
|
||||||
|
}
|
||||||
|
|
||||||
public static AddProfileDialogResult AddProfileDialog(List<Profile> profiles)
|
public static AddProfileDialogResult AddProfileDialog(List<Profile> profiles)
|
||||||
{
|
{
|
||||||
var dialog = new AddProfileDialog(profiles);
|
var dialog = new AddProfileDialog(profiles);
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using MSFSPopoutPanelManager.Orchestration;
|
using Microsoft.Web.WebView2.Core;
|
||||||
|
using MSFSPopoutPanelManager.Orchestration;
|
||||||
using MSFSPopoutPanelManager.Shared;
|
using MSFSPopoutPanelManager.Shared;
|
||||||
using MSFSPopoutPanelManager.UserDataAgent;
|
using MSFSPopoutPanelManager.UserDataAgent;
|
||||||
using MSFSPopoutPanelManager.WindowsAgent;
|
using MSFSPopoutPanelManager.WindowsAgent;
|
||||||
|
@ -12,12 +13,13 @@ namespace MSFSPopoutPanelManager.WpfApp.ViewModel
|
||||||
{
|
{
|
||||||
private MainOrchestrator _orchestrator;
|
private MainOrchestrator _orchestrator;
|
||||||
private bool _minimizeForPopOut;
|
private bool _minimizeForPopOut;
|
||||||
|
private CoreWebView2Environment _coreWebView2Environment;
|
||||||
|
|
||||||
public OrchestratorHelper(MainOrchestrator orchestrator)
|
public OrchestratorHelper(MainOrchestrator orchestrator)
|
||||||
{
|
{
|
||||||
_orchestrator = orchestrator;
|
_orchestrator = orchestrator;
|
||||||
|
|
||||||
_orchestrator.PanelSource.onOverlayShowed += HandleShowOverlay;
|
_orchestrator.PanelSource.OnOverlayShowed += HandleShowOverlay;
|
||||||
_orchestrator.PanelSource.OnLastOverlayRemoved += (sender, e) => HandleRemovePanelSourceOverlay(false);
|
_orchestrator.PanelSource.OnLastOverlayRemoved += (sender, e) => HandleRemovePanelSourceOverlay(false);
|
||||||
_orchestrator.PanelSource.OnAllOverlaysRemoved += (sender, e) => HandleRemovePanelSourceOverlay(true);
|
_orchestrator.PanelSource.OnAllOverlaysRemoved += (sender, e) => HandleRemovePanelSourceOverlay(true);
|
||||||
_orchestrator.PanelSource.OnSelectionStarted += HandlePanelSelectionStarted;
|
_orchestrator.PanelSource.OnSelectionStarted += HandlePanelSelectionStarted;
|
||||||
|
@ -26,6 +28,7 @@ namespace MSFSPopoutPanelManager.WpfApp.ViewModel
|
||||||
_orchestrator.PanelPopOut.OnPopOutStarted += HandleOnPopOutStarted;
|
_orchestrator.PanelPopOut.OnPopOutStarted += HandleOnPopOutStarted;
|
||||||
_orchestrator.PanelPopOut.OnPopOutCompleted += HandleOnPopOutCompleted;
|
_orchestrator.PanelPopOut.OnPopOutCompleted += HandleOnPopOutCompleted;
|
||||||
_orchestrator.PanelPopOut.OnTouchPanelOpened += HandleOnTouchPanelOpened;
|
_orchestrator.PanelPopOut.OnTouchPanelOpened += HandleOnTouchPanelOpened;
|
||||||
|
_orchestrator.PanelPopOut.OnPanelSourceOverlayFlashed += HandleOnPanelSourceOverlayFlashed;
|
||||||
|
|
||||||
StatusMessageWriter.OnStatusMessage += HandleOnStatusMessage;
|
StatusMessageWriter.OnStatusMessage += HandleOnStatusMessage;
|
||||||
}
|
}
|
||||||
|
@ -72,6 +75,16 @@ namespace MSFSPopoutPanelManager.WpfApp.ViewModel
|
||||||
AddPanelCoorOverlay(e);
|
AddPanelCoorOverlay(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void HandleOnPanelSourceOverlayFlashed(object sender, PanelSourceCoordinate e)
|
||||||
|
{
|
||||||
|
Application.Current.Dispatcher.Invoke(() =>
|
||||||
|
{
|
||||||
|
AddPanelCoorOverlay(e);
|
||||||
|
System.Threading.Thread.Sleep(750);
|
||||||
|
HandleRemovePanelSourceOverlay(true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private void HandleRemovePanelSourceOverlay(bool removeAll)
|
private void HandleRemovePanelSourceOverlay(bool removeAll)
|
||||||
{
|
{
|
||||||
Application.Current.Dispatcher.Invoke(() =>
|
Application.Current.Dispatcher.Invoke(() =>
|
||||||
|
@ -113,9 +126,15 @@ namespace MSFSPopoutPanelManager.WpfApp.ViewModel
|
||||||
|
|
||||||
private void HandleOnTouchPanelOpened(object sender, TouchPanelOpenEventArg e)
|
private void HandleOnTouchPanelOpened(object sender, TouchPanelOpenEventArg e)
|
||||||
{
|
{
|
||||||
Application.Current.Dispatcher.Invoke(() =>
|
Application.Current.Dispatcher.Invoke(async () =>
|
||||||
{
|
{
|
||||||
TouchPanelWebViewDialog window = new TouchPanelWebViewDialog(e.PlaneId, e.PanelId, e.Caption, e.Width, e.Height);
|
if (_coreWebView2Environment == null)
|
||||||
|
{
|
||||||
|
var options = new CoreWebView2EnvironmentOptions("--disable-web-security");
|
||||||
|
_coreWebView2Environment = await CoreWebView2Environment.CreateAsync(null, null, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
TouchPanelWebViewDialog window = new TouchPanelWebViewDialog(e.PlaneId, e.PanelId, e.Caption, e.Width, e.Height, _coreWebView2Environment);
|
||||||
window.Show();
|
window.Show();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,17 +45,23 @@ namespace MSFSPopoutPanelManager.WpfApp.ViewModel
|
||||||
.ObservesProperty(() => ProfileData.ActiveProfile)
|
.ObservesProperty(() => ProfileData.ActiveProfile)
|
||||||
.ObservesProperty(() => FlightSimData.IsSimulatorStarted);
|
.ObservesProperty(() => FlightSimData.IsSimulatorStarted);
|
||||||
|
|
||||||
|
SetIncludeInGamePanelsCommand = new DelegateCommand(() => ProfileData.WriteProfiles(), () => FlightSimData.HasCurrentMsfsAircraft && ProfileData.HasActiveProfile && FlightSimData.IsSimulatorStarted)
|
||||||
|
.ObservesProperty(() => FlightSimData.HasCurrentMsfsAircraft)
|
||||||
|
.ObservesProperty(() => ProfileData.ActiveProfile)
|
||||||
|
.ObservesProperty(() => FlightSimData.IsSimulatorStarted);
|
||||||
|
|
||||||
StartPanelSelectionCommand = new DelegateCommand(OnStartPanelSelection, () => FlightSimData.HasCurrentMsfsAircraft && ProfileData.HasActiveProfile && ProfileData.ActiveProfile != null && FlightSimData.IsSimulatorStarted && FlightSimData.IsInCockpit)
|
StartPanelSelectionCommand = new DelegateCommand(OnStartPanelSelection, () => FlightSimData.HasCurrentMsfsAircraft && ProfileData.HasActiveProfile && ProfileData.ActiveProfile != null && FlightSimData.IsSimulatorStarted && FlightSimData.IsInCockpit)
|
||||||
.ObservesProperty(() => FlightSimData.HasCurrentMsfsAircraft)
|
.ObservesProperty(() => FlightSimData.HasCurrentMsfsAircraft)
|
||||||
.ObservesProperty(() => ProfileData.ActiveProfile)
|
.ObservesProperty(() => ProfileData.ActiveProfile)
|
||||||
.ObservesProperty(() => FlightSimData.IsSimulatorStarted)
|
.ObservesProperty(() => FlightSimData.IsSimulatorStarted)
|
||||||
.ObservesProperty(() => FlightSimData.IsInCockpit);
|
.ObservesProperty(() => FlightSimData.IsInCockpit);
|
||||||
|
|
||||||
StartPopOutCommand = new DelegateCommand(OnStartPopOut, () => FlightSimData.HasCurrentMsfsAircraft && ProfileData.HasActiveProfile && (ProfileData.ActiveProfile.PanelSourceCoordinates.Count > 0 || ProfileData.ActiveProfile.TouchPanelBindings.Count > 0) && FlightSimData.IsSimulatorStarted && FlightSimData.IsInCockpit)
|
StartPopOutCommand = new DelegateCommand(OnStartPopOut, () => FlightSimData.HasCurrentMsfsAircraft && ProfileData.HasActiveProfile && (ProfileData.ActiveProfile.PanelSourceCoordinates.Count > 0 || ProfileData.ActiveProfile.TouchPanelBindings.Count > 0 || ProfileData.ActiveProfile.IncludeInGamePanels) && FlightSimData.IsSimulatorStarted && FlightSimData.IsInCockpit)
|
||||||
.ObservesProperty(() => FlightSimData.HasCurrentMsfsAircraft)
|
.ObservesProperty(() => FlightSimData.HasCurrentMsfsAircraft)
|
||||||
.ObservesProperty(() => ProfileData.ActiveProfile)
|
.ObservesProperty(() => ProfileData.ActiveProfile)
|
||||||
.ObservesProperty(() => ProfileData.ActiveProfile.PanelSourceCoordinates.Count)
|
.ObservesProperty(() => ProfileData.ActiveProfile.PanelSourceCoordinates.Count)
|
||||||
.ObservesProperty(() => ProfileData.ActiveProfile.TouchPanelBindings.Count)
|
.ObservesProperty(() => ProfileData.ActiveProfile.TouchPanelBindings.Count)
|
||||||
|
.ObservesProperty(() => ProfileData.ActiveProfile.IncludeInGamePanels)
|
||||||
.ObservesProperty(() => FlightSimData.IsSimulatorStarted)
|
.ObservesProperty(() => FlightSimData.IsSimulatorStarted)
|
||||||
.ObservesProperty(() => FlightSimData.IsInCockpit);
|
.ObservesProperty(() => FlightSimData.IsInCockpit);
|
||||||
|
|
||||||
|
@ -94,6 +100,8 @@ namespace MSFSPopoutPanelManager.WpfApp.ViewModel
|
||||||
|
|
||||||
public DelegateCommand SetPowerOnRequiredCommand { get; private set; }
|
public DelegateCommand SetPowerOnRequiredCommand { get; private set; }
|
||||||
|
|
||||||
|
public DelegateCommand SetIncludeInGamePanelsCommand { get; private set; }
|
||||||
|
|
||||||
public DelegateCommand StartPanelSelectionCommand { get; private set; }
|
public DelegateCommand StartPanelSelectionCommand { get; private set; }
|
||||||
|
|
||||||
public DelegateCommand StartPopOutCommand { get; private set; }
|
public DelegateCommand StartPopOutCommand { get; private set; }
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using MSFSPopoutPanelManager.Orchestration;
|
using MSFSPopoutPanelManager.Orchestration;
|
||||||
using MSFSPopoutPanelManager.Shared;
|
using MSFSPopoutPanelManager.Shared;
|
||||||
using Prism.Commands;
|
using Prism.Commands;
|
||||||
|
using System.Windows;
|
||||||
|
|
||||||
namespace MSFSPopoutPanelManager.WpfApp.ViewModel
|
namespace MSFSPopoutPanelManager.WpfApp.ViewModel
|
||||||
{
|
{
|
||||||
|
@ -20,6 +21,8 @@ namespace MSFSPopoutPanelManager.WpfApp.ViewModel
|
||||||
SectionSelectCommand = new DelegateCommand<object>(OnSectionSelected);
|
SectionSelectCommand = new DelegateCommand<object>(OnSectionSelected);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Window Window { get; set; }
|
||||||
|
|
||||||
public DelegateCommand<object> SectionSelectCommand { get; private set; }
|
public DelegateCommand<object> SectionSelectCommand { get; private set; }
|
||||||
|
|
||||||
public AppSettingData AppSettingData { get { return _orchestrator.AppSettingData; } }
|
public AppSettingData AppSettingData { get { return _orchestrator.AppSettingData; } }
|
||||||
|
@ -36,6 +39,8 @@ namespace MSFSPopoutPanelManager.WpfApp.ViewModel
|
||||||
|
|
||||||
public bool MSFSTouchPanelSettingsVisible { get; private set; }
|
public bool MSFSTouchPanelSettingsVisible { get; private set; }
|
||||||
|
|
||||||
|
public bool WindowedModeSettingsVisible { get; private set; }
|
||||||
|
|
||||||
private void OnSectionSelected(object commandParameter)
|
private void OnSectionSelected(object commandParameter)
|
||||||
{
|
{
|
||||||
ApplicationSettingsVisible = false;
|
ApplicationSettingsVisible = false;
|
||||||
|
@ -44,6 +49,7 @@ namespace MSFSPopoutPanelManager.WpfApp.ViewModel
|
||||||
TrackIRSettingsVisible = false;
|
TrackIRSettingsVisible = false;
|
||||||
TouchSettingsVisible = false;
|
TouchSettingsVisible = false;
|
||||||
MSFSTouchPanelSettingsVisible = false;
|
MSFSTouchPanelSettingsVisible = false;
|
||||||
|
WindowedModeSettingsVisible = false;
|
||||||
|
|
||||||
switch (commandParameter.ToString())
|
switch (commandParameter.ToString())
|
||||||
{
|
{
|
||||||
|
@ -65,6 +71,9 @@ namespace MSFSPopoutPanelManager.WpfApp.ViewModel
|
||||||
case "MSFS Touch Panel Settings":
|
case "MSFS Touch Panel Settings":
|
||||||
MSFSTouchPanelSettingsVisible = true;
|
MSFSTouchPanelSettingsVisible = true;
|
||||||
break;
|
break;
|
||||||
|
case "Windowed Mode Settings":
|
||||||
|
WindowedModeSettingsVisible = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,9 +14,9 @@
|
||||||
<RootNamespace>MSFSPopoutPanelManager.WpfApp</RootNamespace>
|
<RootNamespace>MSFSPopoutPanelManager.WpfApp</RootNamespace>
|
||||||
<ApplicationIcon>logo.ico</ApplicationIcon>
|
<ApplicationIcon>logo.ico</ApplicationIcon>
|
||||||
<Platforms>x64</Platforms>
|
<Platforms>x64</Platforms>
|
||||||
<Version>3.4.2.0</Version>
|
<Version>3.4.3.0</Version>
|
||||||
<AssemblyVersion>3.4.2.0</AssemblyVersion>
|
<AssemblyVersion>3.4.3.0</AssemblyVersion>
|
||||||
<FileVersion>3.4.2.0</FileVersion>
|
<FileVersion>3.4.3.0</FileVersion>
|
||||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||||
<DebugType>embedded</DebugType>
|
<DebugType>embedded</DebugType>
|
||||||
<SatelliteResourceLanguages>en</SatelliteResourceLanguages>
|
<SatelliteResourceLanguages>en</SatelliteResourceLanguages>
|
||||||
|
@ -69,13 +69,13 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Autoupdater.NET.Official" Version="1.7.0" />
|
<PackageReference Include="Autoupdater.NET.Official" Version="1.7.0" />
|
||||||
<PackageReference Include="CalcBinding" Version="2.5.2" />
|
<PackageReference Include="CalcBinding" Version="2.5.2" />
|
||||||
<PackageReference Include="CoordinateSharp" Version="2.13.1.1" Condition=" '$(Configuration)' == 'ReleaseTouchPanel' "/>
|
<PackageReference Include="CoordinateSharp" Version="2.13.1.1" Condition=" '$(Configuration)' == 'ReleaseTouchPanel' " />
|
||||||
<PackageReference Include="Fody" Version="6.6.3">
|
<PackageReference Include="Fody" Version="6.6.3">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="Hardcodet.NotifyIcon.Wpf" Version="1.1.0" />
|
<PackageReference Include="Hardcodet.NotifyIcon.Wpf" Version="1.1.0" />
|
||||||
<PackageReference Include="ini-parser-netcore3.1" Version="3.0.0" Condition=" '$(Configuration)' == 'ReleaseTouchPanel' "/>
|
<PackageReference Include="ini-parser-netcore3.1" Version="3.0.0" Condition=" '$(Configuration)' == 'ReleaseTouchPanel' " />
|
||||||
<PackageReference Include="InputSimulatorCore" Version="1.0.5" />
|
<PackageReference Include="InputSimulatorCore" Version="1.0.5" />
|
||||||
<PackageReference Include="log4net" Version="2.0.14" />
|
<PackageReference Include="log4net" Version="2.0.14" />
|
||||||
<PackageReference Include="MahApps.Metro" Version="2.4.9" />
|
<PackageReference Include="MahApps.Metro" Version="2.4.9" />
|
||||||
|
@ -89,7 +89,7 @@
|
||||||
<PackageReference Include="WindowsHook" Version="1.0.1" />
|
<PackageReference Include="WindowsHook" Version="1.0.1" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.SpaServices" Version="3.1.27" Condition=" '$(Configuration)' == 'ReleaseTouchPanel' Or '$(Configuration)' == 'DebugTouchPanel' " />
|
<PackageReference Include="Microsoft.AspNetCore.SpaServices" Version="3.1.27" Condition=" '$(Configuration)' == 'ReleaseTouchPanel' Or '$(Configuration)' == 'DebugTouchPanel' " />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.SpaServices.Extensions" Version="6.0.7" Condition=" '$(Configuration)' == 'ReleaseTouchPanel' Or '$(Configuration)' == 'DebugTouchPanel' " />
|
<PackageReference Include="Microsoft.AspNetCore.SpaServices.Extensions" Version="6.0.7" Condition=" '$(Configuration)' == 'ReleaseTouchPanel' Or '$(Configuration)' == 'DebugTouchPanel' " />
|
||||||
<PackageReference Include="Microsoft.Web.WebView2" Version="1.0.1264.42" />
|
<PackageReference Include="Microsoft.Web.WebView2" Version="1.0.1293.44" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
@ -1,39 +1,21 @@
|
||||||
Version 3.4.2.0
|
Version 3.4.3.0
|
||||||
|
|
||||||
This release is optional and please feel to skip this update.
|
This release is optional and please feel to skip this update.
|
||||||
|
|
||||||
Change Log:
|
Change Log:
|
||||||
|
|
||||||
* Major change in how profile is bound to an aircraft. Previously, a profile is bound to an
|
* Added ability to remember MSFS game window size and location for aircraft profile when
|
||||||
aircraft livery which requires you to activate binding when switching livery for the same
|
running the game in windows display mode. This new setting is used to resize game window to
|
||||||
aircraft. With this update, a profile is now bound to an aircraft so you no longer need to
|
match original size and location of MSFS game window when panel profile was defined
|
||||||
perform the binding step when switching livery. As you change active aircraft to fly, all
|
initially. For existing aircraft profile, when running the game in windows display mode,
|
||||||
existing livery binding will be automatically converted to aircraft binding if one exists.
|
the profile will automatically save MSFS game window position after the first successful
|
||||||
Also, a profile can still be bound to multiple aircrafts if you so choose such as when
|
pop out.
|
||||||
flying multiple variations of Cessna 172. This change has been a long awaited request to
|
|
||||||
simplify your profile bindings.
|
|
||||||
|
|
||||||
* Added auto assignment of aircraft binding for a newly created profile if the active
|
* Added ability to include in-game menu bar panels such as VFR Map, ATC, Checklist, etc to
|
||||||
aircraft has no previous profile binding specified.
|
aircraft profile. During the pop out process, if any in-game menu bar panels are in popped
|
||||||
|
out state, they will be included in panel configurations. This feature will only work if
|
||||||
|
in-game menu bar panels are popped out initially and it also rely on MSFS re-opens these
|
||||||
|
panels when flight starts (SU 10+).
|
||||||
|
|
||||||
* Added new keyboard shortcuts to move and resize pop outs. Please click on a new
|
* Added UI cue to show number circles momentarily when popping out panel to facilitate
|
||||||
information icon in the upper right corner of panel configuration screen for instruction in
|
troubleshooting.
|
||||||
how to use these new keyboard shortcuts.
|
|
||||||
|
|
||||||
* Added new setting to minimize pop out manager after panels have been popped out.
|
|
||||||
|
|
||||||
* Added work around for SU10 Beta issue when after panel separations, panels' size become
|
|
||||||
so big and they block most of the game window for lower resolution screen and prevented Pop
|
|
||||||
Out Panel Manager from popping out the next panel.
|
|
||||||
|
|
||||||
* Made improvements to how panels are separated during pop out process.
|
|
||||||
|
|
||||||
* Fixed an issue when adjusting position and size of a pop out panel on some PC
|
|
||||||
configuration.
|
|
||||||
|
|
||||||
Known issue:
|
|
||||||
|
|
||||||
* When changing the width or height of a pop up that has Hide Title Bar enable, it will
|
|
||||||
sometime break the Hide Title Bar setting and the only way to fix this is to re-pop out the
|
|
||||||
panel. Currently, this is a bug in MSFS in how it handles the sizing and rendering of pop
|
|
||||||
outs window.
|
|
Loading…
Reference in a new issue