Compare commits
37 Commits
Author | SHA1 | Date |
---|---|---|
![]() |
a68aa187c7 | |
![]() |
a2b63c607a | |
![]() |
76f39d5be8 | |
![]() |
643fb31505 | |
![]() |
df962b7304 | |
![]() |
289b4f2ff5 | |
![]() |
f12494faf3 | |
![]() |
6e8500a479 | |
![]() |
79e2ea3fcd | |
![]() |
0815b20ee8 | |
![]() |
f39fead973 | |
![]() |
f239e9b534 | |
![]() |
f75d77c66a | |
![]() |
3571776b83 | |
![]() |
0347c983b6 | |
![]() |
066ecf6850 | |
![]() |
3eb9c1438a | |
![]() |
179a6a256a | |
![]() |
3f8236506a | |
![]() |
4d36fc7c64 | |
![]() |
81edbde5cc | |
![]() |
3a8d0e59c4 | |
![]() |
a01cdd6dfa | |
![]() |
9d06a0293a | |
![]() |
ee47b30a90 | |
![]() |
3b7aa9c11e | |
![]() |
a0cfa9c0c6 | |
![]() |
2033b5e145 | |
![]() |
a0364ef46b | |
![]() |
7d67cb9437 | |
![]() |
4bd11f9f25 | |
![]() |
c24e4a47a2 | |
![]() |
9c1057dbc5 | |
![]() |
06edb9fcfc | |
![]() |
621f90937f | |
![]() |
b6872dde34 | |
![]() |
48cdfd0e72 |
|
@ -0,0 +1,23 @@
|
|||
---
|
||||
name: Bug report
|
||||
about: 'Create a report to help improve the application '
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Please describe the issue in English if possible**
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is and when it occurs. Please include the app version and any logs/crash dumps.
|
||||
For the portable version of the application these can be found in the same directory as the exe.
|
||||
For installed version of the application these can be found under `%LOCALAPPDATA%/WpfMaiTouchEmulator`
|
||||
|
||||
**To Reproduce**
|
||||
|
||||
**Screenshots**
|
||||
If applicable, add screenshots/videos to help explain your problem.
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
|
@ -0,0 +1,19 @@
|
|||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Please fill out in English if possible**
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
|
@ -1,41 +1,3 @@
|
|||
# This workflow uses actions that are not certified by GitHub.
|
||||
# They are provided by a third-party and are governed by
|
||||
# separate terms of service, privacy policy, and support
|
||||
# documentation.
|
||||
|
||||
# This workflow will build, test, sign and package a WPF or Windows Forms desktop application
|
||||
# built on .NET Core.
|
||||
# To learn how to migrate your existing application to .NET Core,
|
||||
# refer to https://docs.microsoft.com/en-us/dotnet/desktop-wpf/migration/convert-project-from-net-framework
|
||||
#
|
||||
# To configure this workflow:
|
||||
#
|
||||
# 1. Configure environment variables
|
||||
# GitHub sets default environment variables for every workflow run.
|
||||
# Replace the variables relative to your project in the "env" section below.
|
||||
#
|
||||
# 2. Signing
|
||||
# Generate a signing certificate in the Windows Application
|
||||
# Packaging Project or add an existing signing certificate to the project.
|
||||
# Next, use PowerShell to encode the .pfx file using Base64 encoding
|
||||
# by running the following Powershell script to generate the output string:
|
||||
#
|
||||
# $pfx_cert = Get-Content '.\SigningCertificate.pfx' -Encoding Byte
|
||||
# [System.Convert]::ToBase64String($pfx_cert) | Out-File 'SigningCertificate_Encoded.txt'
|
||||
#
|
||||
# Open the output file, SigningCertificate_Encoded.txt, and copy the
|
||||
# string inside. Then, add the string to the repo as a GitHub secret
|
||||
# and name it "Base64_Encoded_Pfx."
|
||||
# For more information on how to configure your signing certificate for
|
||||
# this workflow, refer to https://github.com/microsoft/github-actions-for-desktop-apps#signing
|
||||
#
|
||||
# Finally, add the signing certificate password to the repo as a secret and name it "Pfx_Key".
|
||||
# See "Build the Windows Application Packaging project" below to see how the secret is used.
|
||||
#
|
||||
# For more information on GitHub Actions, refer to https://github.com/features/actions
|
||||
# For a complete CI/CD sample to get started with GitHub Action workflows for Desktop Applications,
|
||||
# refer to https://github.com/microsoft/github-actions-for-desktop-apps
|
||||
|
||||
name: .NET Core Desktop
|
||||
|
||||
on:
|
||||
|
@ -53,13 +15,11 @@ jobs:
|
|||
matrix:
|
||||
configuration: [Release]
|
||||
|
||||
runs-on: windows-latest # For a list of available runner types, refer to
|
||||
# https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idruns-on
|
||||
|
||||
runs-on: windows-latest
|
||||
env:
|
||||
Solution_Name: WpfMaiTouchEmulator.sln # Replace with your solution name, i.e. MyWpfApp.sln.
|
||||
Wap_Project_Directory: . # Replace with the Wap project directory relative to the solution, i.e. MyWpfApp.Package.
|
||||
Wap_Project_Path: WpfMaiTouchEmulator.csproj # Replace with the path to your Wap project, i.e. MyWpf.App.Package\MyWpfApp.Package.wapproj.
|
||||
Solution_Name: WpfMaiTouchEmulator.sln
|
||||
Wap_Project_Directory: .
|
||||
Wap_Project_Path: WpfMaiTouchEmulator.csproj
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
|
@ -92,20 +52,38 @@ jobs:
|
|||
|
||||
# Create the app package by building and packaging the Windows Application Packaging project
|
||||
- name: Create the app package
|
||||
run: msbuild $env:Wap_Project_Path /p:Configuration=$env:Configuration /p:UapAppxPackageBuildMode=$env:Appx_Package_Build_Mode /p:AppxBundle=$env:Appx_Bundle /p:PackageCertificateKeyFile=GitHubActionsWorkflow.pfx /p:PackageCertificatePassword=${{ secrets.Pfx_Key }}
|
||||
run: msbuild $env:Wap_Project_Path /p:Configuration=$env:Configuration /p:UapAppxPackageBuildMode=$env:Appx_Package_Build_Mode /p:AppxBundle=$env:Appx_Bundle /p:PackageCertificateKeyFile=GitHubActionsWorkflow.pfx /p:PackageCertificatePassword=${{ secrets.Pfx_Key }} /p:Version=1.5.0.${{ github.run_number }}
|
||||
env:
|
||||
Appx_Bundle: Always
|
||||
Appx_Bundle_Platforms: x86|x64
|
||||
Appx_Package_Build_Mode: StoreUpload
|
||||
Configuration: ${{ matrix.configuration }}
|
||||
|
||||
- name: Build AIP
|
||||
uses: caphyon/advinst-github-action@v2.0
|
||||
with:
|
||||
advinst-version: '22.2'
|
||||
advinst-enable-automation: 'true'
|
||||
aip-path: ${{ github.workspace }}\Installer\Mai Touch Emulator.aip
|
||||
aip-build-name: DefaultBuild
|
||||
aip-package-name: installMaiTouchEmulator.msi
|
||||
aip-output-dir: ${{ github.workspace }}\setup
|
||||
aip-commands: |
|
||||
SetProperty FOO="foo"
|
||||
SetVersion 1.5.0.${{ github.run_number }}
|
||||
|
||||
# Remove the pfx
|
||||
- name: Remove the pfx
|
||||
run: Remove-Item -path $env:Wap_Project_Directory\GitHubActionsWorkflow.pfx
|
||||
|
||||
# Upload the MSIX package: https://github.com/marketplace/actions/upload-a-build-artifact
|
||||
- name: Upload build artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: Emulator package
|
||||
path: ./bin/Release/net8.0-windows/
|
||||
name: MaiTouchEmulatorPortable
|
||||
path: ./bin/Release/net8.0-windows10.0.17763.0/
|
||||
|
||||
- name: Publish setup artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: MaiTouchEmulatorInstaller
|
||||
path: ./setup/installMaiTouchEmulator.msi
|
||||
|
|
|
@ -360,4 +360,6 @@ MigrationBackup/
|
|||
.ionide/
|
||||
|
||||
# Fody - auto-generated XML schema
|
||||
FodyWeavers.xsd
|
||||
FodyWeavers.xsd
|
||||
|
||||
Installer/
|
||||
|
|
15
App.config
15
App.config
|
@ -25,6 +25,21 @@
|
|||
<setting name="UserLanguage" serializeAs="String">
|
||||
<value />
|
||||
</setting>
|
||||
<setting name="IsRingButtonEmulationEnabled" serializeAs="String">
|
||||
<value>True</value>
|
||||
</setting>
|
||||
<setting name="BorderSetting" serializeAs="String">
|
||||
<value>0</value>
|
||||
</setting>
|
||||
<setting name="BorderColour" serializeAs="String">
|
||||
<value />
|
||||
</setting>
|
||||
<setting name="UserSettingsUpgradeRequired" serializeAs="String">
|
||||
<value>True</value>
|
||||
</setting>
|
||||
<setting name="IsLargeButtonsEnabled" serializeAs="String">
|
||||
<value>False</value>
|
||||
</setting>
|
||||
</WpfMaiTouchEmulator.Properties.Settings>
|
||||
</userSettings>
|
||||
</configuration>
|
8
App.xaml
8
App.xaml
|
@ -2,8 +2,14 @@
|
|||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="clr-namespace:WpfMaiTouchEmulator"
|
||||
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
|
||||
StartupUri="MainWindow.xaml">
|
||||
<Application.Resources>
|
||||
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ui:ThemesDictionary Theme="Light" />
|
||||
<ui:ControlsDictionary />
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
</ResourceDictionary>
|
||||
</Application.Resources>
|
||||
</Application>
|
||||
|
|
|
@ -28,7 +28,7 @@ public partial class App : Application
|
|||
|
||||
private void CreateDump(Exception exception)
|
||||
{
|
||||
var dumpFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "CrashDump.dmp");
|
||||
var dumpFilePath = Path.Combine(Logger.GetLogPath(), "CrashDump.dmp");
|
||||
|
||||
using (var fs = new FileStream(dumpFilePath, FileMode.Create))
|
||||
{
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 217 KiB |
Binary file not shown.
After Width: | Height: | Size: 132 KiB |
Binary file not shown.
After Width: | Height: | Size: 20 KiB |
|
@ -0,0 +1,287 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<DOCUMENT Type="Advanced Installer" CreateVersion="22.2" version="22.2" Modules="simple" RootPath="." Language="en" Id="{B5359581-6E04-4DC3-88F2-8DB4D3AD09E6}">
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiPropsComponent">
|
||||
<ROW Property="AI_APP_FILE" Value="[#WpfMaiTouchEmulator.exe]"/>
|
||||
<ROW Property="AI_BITMAP_DISPLAY_MODE" Value="0"/>
|
||||
<ROW Property="AI_PREDEF_LCONDS_PROPS" Value="AI_DETECTED_ADMIN_USER;AI_DETECTED_DOTNET_CORE_VERSION"/>
|
||||
<ROW Property="AI_REQUIRED_DOTNET_CORE_DISPLAY" MultiBuildValue="DefaultBuild:8.0" ValueLocId="-"/>
|
||||
<ROW Property="AI_REQUIRED_DOTNET_CORE_VERSION" MultiBuildValue="DefaultBuild:8.0" ValueLocId="-"/>
|
||||
<ROW Property="ALLUSERS" Value="1" MultiBuildValue="DefaultBuild:2"/>
|
||||
<ROW Property="ARPCOMMENTS" Value="This installer database contains the logic and data required to install [|ProductName]." ValueLocId="*"/>
|
||||
<ROW Property="ARPPRODUCTICON" Value="icon.exe" Type="8"/>
|
||||
<ROW Property="CTRLS" Value="2"/>
|
||||
<ROW Property="Manufacturer" Value="Leapward-Koex"/>
|
||||
<ROW Property="ProductCode" Value="1033:{08E138ED-9CC0-4CF8-BC4A-E0B7B270D5F7} " Type="16"/>
|
||||
<ROW Property="ProductLanguage" Value="1033"/>
|
||||
<ROW Property="ProductName" Value="Mai Touch Emulator"/>
|
||||
<ROW Property="ProductVersion" Value="1.0.0" Options="32"/>
|
||||
<ROW Property="REBOOT" MultiBuildValue="DefaultBuild:ReallySuppress"/>
|
||||
<ROW Property="SecureCustomProperties" Value="OLDPRODUCTS;AI_NEWERPRODUCTFOUND"/>
|
||||
<ROW Property="UpgradeCode" Value="{464CA79D-14BC-45BC-AE26-F5C4D59346C9}"/>
|
||||
<ROW Property="WindowsType9X" MultiBuildValue="DefaultBuild:Windows 9x/ME" ValueLocId="-"/>
|
||||
<ROW Property="WindowsType9XDisplay" MultiBuildValue="DefaultBuild:Windows 9x/ME" ValueLocId="-"/>
|
||||
<ROW Property="WindowsTypeNT" MultiBuildValue="DefaultBuild:Windows 7 x86, Windows 8 x86, Windows 8.1 x86" ValueLocId="-"/>
|
||||
<ROW Property="WindowsTypeNT40" MultiBuildValue="DefaultBuild:Windows NT 4.0" ValueLocId="-"/>
|
||||
<ROW Property="WindowsTypeNT40Display" MultiBuildValue="DefaultBuild:Windows NT 4.0" ValueLocId="-"/>
|
||||
<ROW Property="WindowsTypeNT50" MultiBuildValue="DefaultBuild:Windows 2000" ValueLocId="-"/>
|
||||
<ROW Property="WindowsTypeNT50Display" MultiBuildValue="DefaultBuild:Windows 2000" ValueLocId="-"/>
|
||||
<ROW Property="WindowsTypeNT5X" MultiBuildValue="DefaultBuild:Windows XP/2003" ValueLocId="-"/>
|
||||
<ROW Property="WindowsTypeNT5XDisplay" MultiBuildValue="DefaultBuild:Windows XP/2003" ValueLocId="-"/>
|
||||
<ROW Property="WindowsTypeNT60" MultiBuildValue="DefaultBuild:Windows Vista/Server 2008" ValueLocId="-"/>
|
||||
<ROW Property="WindowsTypeNT60Display" MultiBuildValue="DefaultBuild:Windows Vista/Server 2008" ValueLocId="-"/>
|
||||
<ROW Property="WindowsTypeNT64" MultiBuildValue="DefaultBuild:Windows 7 x64, Windows Server 2008 R2 x64, Windows 8 x64, Windows Server 2012 x64, Windows 8.1 x64, Windows Server 2012 R2 x64, Windows Server x64" ValueLocId="-"/>
|
||||
<ROW Property="WindowsTypeNT64Display" MultiBuildValue="DefaultBuild:Windows 7 x64, Windows Server 2008 R2 x64, Windows 8 x64, Windows Server 2012 x64, Windows 8.1 x64, Windows Server 2012 R2 x64, Windows Server x64" ValueLocId="-"/>
|
||||
<ROW Property="WindowsTypeNTDisplay" MultiBuildValue="DefaultBuild:Windows 7 x86, Windows 8 x86, Windows 8.1 x86" ValueLocId="-"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiDirsComponent">
|
||||
<ROW Directory="APPDIR" Directory_Parent="TARGETDIR" DefaultDir="APPDIR:." IsPseudoRoot="1"/>
|
||||
<ROW Directory="ProgramMenuFolder" Directory_Parent="TARGETDIR" DefaultDir="PROGRA~1|ProgramMenuFolder" IsPseudoRoot="1"/>
|
||||
<ROW Directory="TARGETDIR" DefaultDir="SourceDir"/>
|
||||
<ROW Directory="com0com_Dir" Directory_Parent="thirdpartyprograms_Dir" DefaultDir="com0com"/>
|
||||
<ROW Directory="jaJP_Dir" Directory_Parent="APPDIR" DefaultDir="ja-JP"/>
|
||||
<ROW Directory="lib_1_Dir" Directory_Parent="win_Dir" DefaultDir="lib"/>
|
||||
<ROW Directory="net8.0_1_Dir" Directory_Parent="lib_1_Dir" DefaultDir="net8.0"/>
|
||||
<ROW Directory="runtimes_Dir" Directory_Parent="APPDIR" DefaultDir="runtimes"/>
|
||||
<ROW Directory="thirdpartyprograms_Dir" Directory_Parent="APPDIR" DefaultDir="THIRDP~1|thirdparty programs"/>
|
||||
<ROW Directory="win_Dir" Directory_Parent="runtimes_Dir" DefaultDir="win"/>
|
||||
<ROW Directory="zhCN_Dir" Directory_Parent="APPDIR" DefaultDir="zh-CN"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.SideBySideGuidComponent">
|
||||
<ROW Component="APPDIR" Value="{E9523757-B9AF-4FE4-8034-0CA60B965037}"/>
|
||||
<ROW Component="ProductInformation" Value="{69562BAB-9822-4EC6-BB86-EA5953730D68}"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiCompsComponent">
|
||||
<ROW Component="AI_INSTALLPERUSER" ComponentId="{8DE0F484-4802-477C-8708-40D881BE6323}" Directory_="APPDIR" Attributes="260" KeyPath="AI_INSTALLPERUSER" Options="1"/>
|
||||
<ROW Component="APPDIR" ComponentId="{E9523757-B9AF-4FE4-8034-0CA60B965037}" Directory_="APPDIR" Attributes="0"/>
|
||||
<ROW Component="Microsoft.Win32.SystemEvents.dll" ComponentId="{1CD260D3-BC38-4E6F-87B3-F243BF6FB3E5}" Directory_="net8.0_1_Dir" Attributes="0" KeyPath="Microsoft.Win32.SystemEvents.dll"/>
|
||||
<ROW Component="Microsoft.Win32.SystemEvents.dll_1" ComponentId="{4FF055E5-90A5-4D0B-869D-81D87D9F5D4C}" Directory_="APPDIR" Attributes="0" KeyPath="Microsoft.Win32.SystemEvents.dll_1"/>
|
||||
<ROW Component="Microsoft.Windows.SDK.NET.dll" ComponentId="{FD3FCBF4-F9D9-4DD6-BDB1-2E462A39154E}" Directory_="APPDIR" Attributes="0" KeyPath="Microsoft.Windows.SDK.NET.dll"/>
|
||||
<ROW Component="ProductInformation" ComponentId="{69562BAB-9822-4EC6-BB86-EA5953730D68}" Directory_="APPDIR" Attributes="260" KeyPath="Version"/>
|
||||
<ROW Component="System.Drawing.Common.dll" ComponentId="{27EDF0B3-615B-49A8-B181-7339D01DC5BD}" Directory_="APPDIR" Attributes="0" KeyPath="System.Drawing.Common.dll"/>
|
||||
<ROW Component="System.IO.Ports.dll" ComponentId="{D776A384-99ED-49DE-8047-4C06A5141960}" Directory_="APPDIR" Attributes="0" KeyPath="System.IO.Ports.dll"/>
|
||||
<ROW Component="System.IO.Ports.dll_1" ComponentId="{767812B6-6569-4A50-917D-F7FAB0DEA8FB}" Directory_="net8.0_1_Dir" Attributes="0" KeyPath="System.IO.Ports.dll_1"/>
|
||||
<ROW Component="System.Private.Windows.Core.dll" ComponentId="{55D5CCEF-9774-4702-950A-F564146D2473}" Directory_="APPDIR" Attributes="0" KeyPath="System.Private.Windows.Core.dll"/>
|
||||
<ROW Component="WinRT.Runtime.dll" ComponentId="{8BEB0AE9-88A8-409E-9129-0A1F2CBE0850}" Directory_="APPDIR" Attributes="0" KeyPath="WinRT.Runtime.dll"/>
|
||||
<ROW Component="Wpf.Ui.dll" ComponentId="{8A193511-50C0-4369-8159-FF599D4CEEB8}" Directory_="APPDIR" Attributes="0" KeyPath="Wpf.Ui.dll"/>
|
||||
<ROW Component="WpfMaiTouchEmulator.deps.json" ComponentId="{CD8C5345-8556-4C3E-AAE9-1E7D90E1DD5A}" Directory_="APPDIR" Attributes="0" KeyPath="WpfMaiTouchEmulator.deps.json" Type="0"/>
|
||||
<ROW Component="WpfMaiTouchEmulator.dll" ComponentId="{B289ACCE-2BAF-436F-814B-D39E91524B89}" Directory_="APPDIR" Attributes="256" KeyPath="WpfMaiTouchEmulator.dll"/>
|
||||
<ROW Component="WpfMaiTouchEmulator.exe" ComponentId="{AA079BFA-401B-4AFA-A56A-92F2A65DB096}" Directory_="APPDIR" Attributes="256" KeyPath="WpfMaiTouchEmulator.exe"/>
|
||||
<ROW Component="WpfMaiTouchEmulator.resources.dll" ComponentId="{01F7375B-D27D-407C-AD17-EE73D183740C}" Directory_="zhCN_Dir" Attributes="256" KeyPath="WpfMaiTouchEmulator.resources.dll"/>
|
||||
<ROW Component="WpfMaiTouchEmulator.resources.dll_1" ComponentId="{27FEB25A-02E1-4D0B-9357-FE31FC757C34}" Directory_="jaJP_Dir" Attributes="256" KeyPath="WpfMaiTouchEmulator.resources.dll_1"/>
|
||||
<ROW Component="com0com.cat" ComponentId="{DE7A59B3-AA91-441B-8E80-99E5B7B56F07}" Directory_="com0com_Dir" Attributes="0" KeyPath="com0com.cat" Type="0"/>
|
||||
<ROW Component="setup.dll" ComponentId="{6DB50EDF-6F89-4A1D-A709-584F83A0B5CF}" Directory_="com0com_Dir" Attributes="256" KeyPath="setup.dll"/>
|
||||
<ROW Component="setupc.exe" ComponentId="{EEA73D45-D23D-4F40-A657-F93D96427FDF}" Directory_="com0com_Dir" Attributes="256" KeyPath="setupc.exe"/>
|
||||
<ROW Component="setupg.exe" ComponentId="{8532B8AB-C539-4A78-A83A-FF8BC1671E15}" Directory_="com0com_Dir" Attributes="0" KeyPath="setupg.exe"/>
|
||||
<ROW Component="uninstall.exe" ComponentId="{645968DC-E43B-43A0-B6A6-A25616A43837}" Directory_="com0com_Dir" Attributes="0" KeyPath="uninstall.exe"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiFeatsComponent">
|
||||
<ROW Feature="MainFeature" Title="MainFeature" Description="Description" Display="1" Level="1" Directory_="APPDIR" Attributes="0"/>
|
||||
<ATTRIBUTE name="CurrentFeature" value="MainFeature"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiFilesComponent">
|
||||
<ROW File="com0com.cat" Component_="com0com.cat" FileName="com0com.cat" Attributes="0" SourcePath="..\bin\Release\net8.0-windows10.0.17763.0\thirdparty programs\com0com\com0com.cat" SelfReg="false"/>
|
||||
<ROW File="com0com.inf" Component_="com0com.cat" FileName="com0com.inf" Attributes="0" SourcePath="..\bin\Release\net8.0-windows10.0.17763.0\thirdparty programs\com0com\com0com.inf" SelfReg="false"/>
|
||||
<ROW File="com0com.sys" Component_="com0com.cat" FileName="com0com.sys" Attributes="0" SourcePath="..\bin\Release\net8.0-windows10.0.17763.0\thirdparty programs\com0com\com0com.sys" SelfReg="false"/>
|
||||
<ROW File="ReadMe.txt" Component_="com0com.cat" FileName="ReadMe.txt" Attributes="0" SourcePath="..\bin\Release\net8.0-windows10.0.17763.0\thirdparty programs\com0com\ReadMe.txt" SelfReg="false"/>
|
||||
<ROW File="setup.dll" Component_="setup.dll" FileName="setup.dll" Attributes="0" SourcePath="..\bin\Release\net8.0-windows10.0.17763.0\thirdparty programs\com0com\setup.dll" SelfReg="false"/>
|
||||
<ROW File="setupc.exe" Component_="setupc.exe" FileName="setupc.exe" Attributes="0" SourcePath="..\bin\Release\net8.0-windows10.0.17763.0\thirdparty programs\com0com\setupc.exe" SelfReg="false" DigSign="true"/>
|
||||
<ROW File="setupg.exe" Component_="setupg.exe" FileName="setupg.exe" Attributes="0" SourcePath="..\bin\Release\net8.0-windows10.0.17763.0\thirdparty programs\com0com\setupg.exe" SelfReg="false" DigSign="true"/>
|
||||
<ROW File="uninstall.exe" Component_="uninstall.exe" FileName="UNINST~1.EXE|uninstall.exe" Attributes="0" SourcePath="..\bin\Release\net8.0-windows10.0.17763.0\thirdparty programs\com0com\uninstall.exe" SelfReg="false" DigSign="true"/>
|
||||
<ROW File="Microsoft.Win32.SystemEvents.dll" Component_="Microsoft.Win32.SystemEvents.dll" FileName="MICROS~1.DLL|Microsoft.Win32.SystemEvents.dll" Attributes="0" SourcePath="..\bin\Release\net8.0-windows10.0.17763.0\runtimes\win\lib\net8.0\Microsoft.Win32.SystemEvents.dll" SelfReg="false"/>
|
||||
<ROW File="System.IO.Ports.dll_1" Component_="System.IO.Ports.dll_1" FileName="SYSTEM~1.DLL|System.IO.Ports.dll" Attributes="0" SourcePath="..\bin\Release\net8.0-windows10.0.17763.0\runtimes\win\lib\net8.0\System.IO.Ports.dll" SelfReg="false"/>
|
||||
<ROW File="WpfMaiTouchEmulator.resources.dll" Component_="WpfMaiTouchEmulator.resources.dll" FileName="WPFMAI~1.DLL|WpfMaiTouchEmulator.resources.dll" Attributes="0" SourcePath="..\bin\Release\net8.0-windows10.0.17763.0\zh-CN\WpfMaiTouchEmulator.resources.dll" SelfReg="false"/>
|
||||
<ROW File="WpfMaiTouchEmulator.resources.dll_1" Component_="WpfMaiTouchEmulator.resources.dll_1" FileName="WPFMAI~1.DLL|WpfMaiTouchEmulator.resources.dll" Attributes="0" SourcePath="..\bin\Release\net8.0-windows10.0.17763.0\ja-JP\WpfMaiTouchEmulator.resources.dll" SelfReg="false"/>
|
||||
<ROW File="Microsoft.Win32.SystemEvents.dll_1" Component_="Microsoft.Win32.SystemEvents.dll_1" FileName="MICROS~1.DLL|Microsoft.Win32.SystemEvents.dll" Attributes="0" SourcePath="..\bin\Release\net8.0-windows10.0.17763.0\Microsoft.Win32.SystemEvents.dll" SelfReg="false"/>
|
||||
<ROW File="Microsoft.Windows.SDK.NET.dll" Component_="Microsoft.Windows.SDK.NET.dll" FileName="MICROS~2.DLL|Microsoft.Windows.SDK.NET.dll" Attributes="0" SourcePath="..\bin\Release\net8.0-windows10.0.17763.0\Microsoft.Windows.SDK.NET.dll" SelfReg="false"/>
|
||||
<ROW File="System.Drawing.Common.dll" Component_="System.Drawing.Common.dll" FileName="SYSTEM~1.DLL|System.Drawing.Common.dll" Attributes="0" SourcePath="..\bin\Release\net8.0-windows10.0.17763.0\System.Drawing.Common.dll" SelfReg="false"/>
|
||||
<ROW File="System.IO.Ports.dll" Component_="System.IO.Ports.dll" FileName="SYSTEM~2.DLL|System.IO.Ports.dll" Attributes="0" SourcePath="..\bin\Release\net8.0-windows10.0.17763.0\System.IO.Ports.dll" SelfReg="false"/>
|
||||
<ROW File="System.Private.Windows.Core.dll" Component_="System.Private.Windows.Core.dll" FileName="SYSTEM~3.DLL|System.Private.Windows.Core.dll" Attributes="0" SourcePath="..\bin\Release\net8.0-windows10.0.17763.0\System.Private.Windows.Core.dll" SelfReg="false"/>
|
||||
<ROW File="WinRT.Runtime.dll" Component_="WinRT.Runtime.dll" FileName="WINRTR~1.DLL|WinRT.Runtime.dll" Attributes="0" SourcePath="..\bin\Release\net8.0-windows10.0.17763.0\WinRT.Runtime.dll" SelfReg="false"/>
|
||||
<ROW File="WpfMaiTouchEmulator.deps.json" Component_="WpfMaiTouchEmulator.deps.json" FileName="WPFMAI~1.JSO|WpfMaiTouchEmulator.deps.json" Attributes="0" SourcePath="..\bin\Release\net8.0-windows10.0.17763.0\WpfMaiTouchEmulator.deps.json" SelfReg="false"/>
|
||||
<ROW File="WpfMaiTouchEmulator.dll" Component_="WpfMaiTouchEmulator.dll" FileName="WPFMAI~1.DLL|WpfMaiTouchEmulator.dll" Attributes="0" SourcePath="..\bin\Release\net8.0-windows10.0.17763.0\WpfMaiTouchEmulator.dll" SelfReg="false"/>
|
||||
<ROW File="WpfMaiTouchEmulator.dll.config" Component_="WpfMaiTouchEmulator.deps.json" FileName="WPFMAI~1.CON|WpfMaiTouchEmulator.dll.config" Attributes="0" SourcePath="..\bin\Release\net8.0-windows10.0.17763.0\WpfMaiTouchEmulator.dll.config" SelfReg="false"/>
|
||||
<ROW File="WpfMaiTouchEmulator.exe" Component_="WpfMaiTouchEmulator.exe" FileName="WPFMAI~1.EXE|WpfMaiTouchEmulator.exe" Attributes="0" SourcePath="..\bin\Release\net8.0-windows10.0.17763.0\WpfMaiTouchEmulator.exe" SelfReg="false" DigSign="true"/>
|
||||
<ROW File="WpfMaiTouchEmulator.runtimeconfig.json" Component_="WpfMaiTouchEmulator.deps.json" FileName="WPFMAI~2.JSO|WpfMaiTouchEmulator.runtimeconfig.json" Attributes="0" SourcePath="..\bin\Release\net8.0-windows10.0.17763.0\WpfMaiTouchEmulator.runtimeconfig.json" SelfReg="false"/>
|
||||
<ROW File="Wpf.Ui.dll" Component_="Wpf.Ui.dll" FileName="WPFUI~1.DLL|Wpf.Ui.dll" Attributes="0" SourcePath="..\bin\Release\net8.0-windows10.0.17763.0\Wpf.Ui.dll" SelfReg="false"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.AiPersistentPropComponent">
|
||||
<ROW Property="AI_INSTALLPERUSER" Registry="AI_INSTALLPERUSER" HklmSearch="AI_INSTALLPERUSER" HkcuSearch="AI_INSTALLPERUSER_1" Hklm64Search="AI_INSTALLPERUSER_2" Hkcu64Search="AI_INSTALLPERUSER_3"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.BootstrapperUISequenceComponent">
|
||||
<ROW Action="AI_DetectSoftware" Sequence="151"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.BuildComponent">
|
||||
<ROW BuildKey="DefaultBuild" BuildName="DefaultBuild" BuildOrder="1" BuildType="0" Languages="en" InstallationType="4" SummInfoMetadata="Page Count:450" UseLargeSchema="true" MsiPackageType="x64"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.DictionaryComponent">
|
||||
<ROW Path="<AI_DICTS>ui.ail"/>
|
||||
<ROW Path="<AI_DICTS>ui_en.ail"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.FragmentComponent">
|
||||
<ROW Fragment="CommonUI.aip" Path="<AI_FRAGS>CommonUI.aip"/>
|
||||
<ROW Fragment="FolderDlg.aip" Path="<AI_THEMES>classic\fragments\FolderDlg.aip"/>
|
||||
<ROW Fragment="InstallTypeDlg.aip" Path="<AI_THEMES>classic\fragments\InstallTypeDlg.aip"/>
|
||||
<ROW Fragment="MaintenanceTypeDlg.aip" Path="<AI_THEMES>classic\fragments\MaintenanceTypeDlg.aip"/>
|
||||
<ROW Fragment="MaintenanceWelcomeDlg.aip" Path="<AI_THEMES>classic\fragments\MaintenanceWelcomeDlg.aip"/>
|
||||
<ROW Fragment="SequenceDialogs.aip" Path="<AI_THEMES>classic\fragments\SequenceDialogs.aip"/>
|
||||
<ROW Fragment="Sequences.aip" Path="<AI_FRAGS>Sequences.aip"/>
|
||||
<ROW Fragment="StaticUIStrings.aip" Path="<AI_FRAGS>StaticUIStrings.aip"/>
|
||||
<ROW Fragment="Themes.aip" Path="<AI_FRAGS>Themes.aip"/>
|
||||
<ROW Fragment="UI.aip" Path="<AI_THEMES>classic\fragments\UI.aip"/>
|
||||
<ROW Fragment="Validation.aip" Path="<AI_FRAGS>Validation.aip"/>
|
||||
<ROW Fragment="VerifyRemoveDlg.aip" Path="<AI_THEMES>classic\fragments\VerifyRemoveDlg.aip"/>
|
||||
<ROW Fragment="VerifyRepairDlg.aip" Path="<AI_THEMES>classic\fragments\VerifyRepairDlg.aip"/>
|
||||
<ROW Fragment="WelcomeDlg.aip" Path="<AI_THEMES>classic\fragments\WelcomeDlg.aip"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiAppSearchComponent">
|
||||
<ROW Property="AI_INSTALLPERUSER" Signature_="AI_INSTALLPERUSER"/>
|
||||
<ROW Property="AI_INSTALLPERUSER" Signature_="AI_INSTALLPERUSER_1"/>
|
||||
<ROW Property="AI_INSTALLPERUSER" Signature_="AI_INSTALLPERUSER_2"/>
|
||||
<ROW Property="AI_INSTALLPERUSER" Signature_="AI_INSTALLPERUSER_3"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiBinaryComponent">
|
||||
<ROW Name="ShortcutFlags.dll" SourcePath="<AI_CUSTACTS>ShortcutFlags.dll"/>
|
||||
<ROW Name="SoftwareDetector.dll" SourcePath="<AI_CUSTACTS>SoftwareDetector.dll"/>
|
||||
<ROW Name="aicustact.dll" SourcePath="<AI_CUSTACTS>aicustact.dll"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiControlEventComponent">
|
||||
<ROW Dialog_="WelcomeDlg" Control_="Next" Event="NewDialog" Argument="InstallTypeDlg" Condition="AI_INSTALL" Ordering="1"/>
|
||||
<ROW Dialog_="FolderDlg" Control_="Next" Event="NewDialog" Argument="VerifyReadyDlg" Condition="AI_INSTALL" Ordering="201"/>
|
||||
<ROW Dialog_="FolderDlg" Control_="Back" Event="NewDialog" Argument="InstallTypeDlg" Condition="AI_INSTALL" Ordering="1"/>
|
||||
<ROW Dialog_="MaintenanceWelcomeDlg" Control_="Next" Event="NewDialog" Argument="MaintenanceTypeDlg" Condition="AI_MAINT" Ordering="99"/>
|
||||
<ROW Dialog_="VerifyReadyDlg" Control_="Install" Event="EndDialog" Argument="Return" Condition="AI_MAINT" Ordering="198"/>
|
||||
<ROW Dialog_="VerifyReadyDlg" Control_="Back" Event="NewDialog" Argument="CustomizeDlg" Condition="AI_MAINT" Ordering="202"/>
|
||||
<ROW Dialog_="VerifyReadyDlg" Control_="Install" Event="EndDialog" Argument="Return" Condition="AI_INSTALL" Ordering="197"/>
|
||||
<ROW Dialog_="VerifyReadyDlg" Control_="Back" Event="NewDialog" Argument="FolderDlg" Condition="AI_INSTALL" Ordering="201"/>
|
||||
<ROW Dialog_="CustomizeDlg" Control_="Next" Event="NewDialog" Argument="VerifyReadyDlg" Condition="AI_MAINT" Ordering="101"/>
|
||||
<ROW Dialog_="CustomizeDlg" Control_="Back" Event="NewDialog" Argument="MaintenanceTypeDlg" Condition="AI_MAINT" Ordering="1"/>
|
||||
<ROW Dialog_="MaintenanceTypeDlg" Control_="ChangeButton" Event="NewDialog" Argument="CustomizeDlg" Condition="AI_MAINT" Ordering="501"/>
|
||||
<ROW Dialog_="MaintenanceTypeDlg" Control_="Back" Event="NewDialog" Argument="MaintenanceWelcomeDlg" Condition="AI_MAINT" Ordering="1"/>
|
||||
<ROW Dialog_="MaintenanceTypeDlg" Control_="RemoveButton" Event="NewDialog" Argument="VerifyRemoveDlg" Condition="AI_MAINT AND InstallMode="Remove"" Ordering="601"/>
|
||||
<ROW Dialog_="VerifyRemoveDlg" Control_="Back" Event="NewDialog" Argument="MaintenanceTypeDlg" Condition="AI_MAINT AND InstallMode="Remove"" Ordering="1"/>
|
||||
<ROW Dialog_="MaintenanceTypeDlg" Control_="RepairButton" Event="NewDialog" Argument="VerifyRepairDlg" Condition="AI_MAINT AND InstallMode="Repair"" Ordering="601"/>
|
||||
<ROW Dialog_="VerifyRepairDlg" Control_="Back" Event="NewDialog" Argument="MaintenanceTypeDlg" Condition="AI_MAINT AND InstallMode="Repair"" Ordering="1"/>
|
||||
<ROW Dialog_="VerifyRepairDlg" Control_="Repair" Event="EndDialog" Argument="Return" Condition="AI_MAINT AND InstallMode="Repair"" Ordering="399" Options="1"/>
|
||||
<ROW Dialog_="VerifyRemoveDlg" Control_="Remove" Event="EndDialog" Argument="Return" Condition="AI_MAINT AND InstallMode="Remove"" Ordering="299" Options="1"/>
|
||||
<ROW Dialog_="PatchWelcomeDlg" Control_="Next" Event="NewDialog" Argument="VerifyReadyDlg" Condition="AI_PATCH" Ordering="201"/>
|
||||
<ROW Dialog_="ResumeDlg" Control_="Install" Event="EndDialog" Argument="Return" Condition="AI_RESUME" Ordering="299"/>
|
||||
<ROW Dialog_="InstallTypeDlg" Control_="Next" Event="NewDialog" Argument="FolderDlg" Condition="AI_INSTALL" Ordering="101"/>
|
||||
<ROW Dialog_="InstallTypeDlg" Control_="Back" Event="NewDialog" Argument="WelcomeDlg" Condition="AI_INSTALL" Ordering="1"/>
|
||||
<ROW Dialog_="VerifyReadyDlg" Control_="Install" Event="EndDialog" Argument="Return" Condition="AI_PATCH" Ordering="199"/>
|
||||
<ROW Dialog_="VerifyReadyDlg" Control_="Back" Event="NewDialog" Argument="PatchWelcomeDlg" Condition="AI_PATCH" Ordering="203"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiCreateFolderComponent">
|
||||
<ROW Directory_="APPDIR" Component_="APPDIR" ManualDelete="true"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiCustActComponent">
|
||||
<ROW Action="AI_ApplyShortcutFlags" Type="3073" Source="ShortcutFlags.dll" Target="UpdateShortcutFlags" WithoutSeq="true"/>
|
||||
<ROW Action="AI_AuthorSinglePackage" Type="1" Source="aicustact.dll" Target="AI_AuthorSinglePackage" WithoutSeq="true"/>
|
||||
<ROW Action="AI_DOWNGRADE" Type="19" Target="4010"/>
|
||||
<ROW Action="AI_DetectSoftware" Type="257" Source="SoftwareDetector.dll" Target="OnDetectSoftware"/>
|
||||
<ROW Action="AI_DpiContentScale" Type="1" Source="aicustact.dll" Target="DpiContentScale"/>
|
||||
<ROW Action="AI_EnableDebugLog" Type="321" Source="aicustact.dll" Target="EnableDebugLog"/>
|
||||
<ROW Action="AI_InstallModeCheck" Type="1" Source="aicustact.dll" Target="UpdateInstallMode" WithoutSeq="true"/>
|
||||
<ROW Action="AI_LaunchApp" Type="1" Source="aicustact.dll" Target="LaunchApp"/>
|
||||
<ROW Action="AI_PREPARE_UPGRADE" Type="65" Source="aicustact.dll" Target="PrepareUpgrade"/>
|
||||
<ROW Action="AI_PRESERVE_INSTALL_TYPE" Type="65" Source="aicustact.dll" Target="PreserveInstallType"/>
|
||||
<ROW Action="AI_PinShortcuts" Type="1" Source="ShortcutFlags.dll" Target="PinShortcuts"/>
|
||||
<ROW Action="AI_PinToStartScreen" Type="1025" Source="ShortcutFlags.dll" Target="PinToStartScreen" WithoutSeq="true"/>
|
||||
<ROW Action="AI_PinToTaskbar" Type="1025" Source="ShortcutFlags.dll" Target="PinToTaskbar" WithoutSeq="true"/>
|
||||
<ROW Action="AI_PrepareShortcutFlags" Type="1" Source="ShortcutFlags.dll" Target="PrepareActionData"/>
|
||||
<ROW Action="AI_RESTORE_LOCATION" Type="65" Source="aicustact.dll" Target="RestoreLocation"/>
|
||||
<ROW Action="AI_ResolveKnownFolders" Type="1" Source="aicustact.dll" Target="AI_ResolveKnownFolders"/>
|
||||
<ROW Action="AI_SETMIXINSTLOCATION" Type="1" Source="aicustact.dll" Target="MixedAllUsersInstallLocation"/>
|
||||
<ROW Action="AI_SHOW_LOG" Type="65" Source="aicustact.dll" Target="LaunchLogFile" WithoutSeq="true"/>
|
||||
<ROW Action="AI_STORE_LOCATION" Type="51" Source="ARPINSTALLLOCATION" Target="[APPDIR]"/>
|
||||
<ROW Action="AI_UnpinFromStartScreen" Type="1025" Source="ShortcutFlags.dll" Target="UnpinFromStartScreen" WithoutSeq="true"/>
|
||||
<ROW Action="AI_UnpinFromTaskbar" Type="1025" Source="ShortcutFlags.dll" Target="UnpinFromTaskbar" WithoutSeq="true"/>
|
||||
<ROW Action="AI_UnpinShortcuts" Type="1" Source="ShortcutFlags.dll" Target="UnpinShortcuts"/>
|
||||
<ROW Action="SET_APPDIR" Type="307" Source="APPDIR" Target="[ProgramFilesFolder][Manufacturer]\[ProductName]" MultiBuildTarget="DefaultBuild:[AI_UserProgramFiles][Manufacturer]\[ProductName]"/>
|
||||
<ROW Action="SET_SHORTCUTDIR" Type="307" Source="SHORTCUTDIR" Target="[ProgramMenuFolder][ProductName]"/>
|
||||
<ROW Action="SET_TARGETDIR_TO_APPDIR" Type="51" Source="TARGETDIR" Target="[APPDIR]"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiFeatCompsComponent">
|
||||
<ROW Feature_="MainFeature" Component_="APPDIR"/>
|
||||
<ROW Feature_="MainFeature" Component_="ProductInformation"/>
|
||||
<ROW Feature_="MainFeature" Component_="AI_INSTALLPERUSER"/>
|
||||
<ROW Feature_="MainFeature" Component_="com0com.cat"/>
|
||||
<ROW Feature_="MainFeature" Component_="setup.dll"/>
|
||||
<ROW Feature_="MainFeature" Component_="setupc.exe"/>
|
||||
<ROW Feature_="MainFeature" Component_="setupg.exe"/>
|
||||
<ROW Feature_="MainFeature" Component_="uninstall.exe"/>
|
||||
<ROW Feature_="MainFeature" Component_="Microsoft.Win32.SystemEvents.dll"/>
|
||||
<ROW Feature_="MainFeature" Component_="System.IO.Ports.dll_1"/>
|
||||
<ROW Feature_="MainFeature" Component_="Microsoft.Win32.SystemEvents.dll_1"/>
|
||||
<ROW Feature_="MainFeature" Component_="WpfMaiTouchEmulator.resources.dll"/>
|
||||
<ROW Feature_="MainFeature" Component_="Microsoft.Windows.SDK.NET.dll"/>
|
||||
<ROW Feature_="MainFeature" Component_="WpfMaiTouchEmulator.resources.dll_1"/>
|
||||
<ROW Feature_="MainFeature" Component_="System.Drawing.Common.dll"/>
|
||||
<ROW Feature_="MainFeature" Component_="System.IO.Ports.dll"/>
|
||||
<ROW Feature_="MainFeature" Component_="System.Private.Windows.Core.dll"/>
|
||||
<ROW Feature_="MainFeature" Component_="WinRT.Runtime.dll"/>
|
||||
<ROW Feature_="MainFeature" Component_="WpfMaiTouchEmulator.deps.json"/>
|
||||
<ROW Feature_="MainFeature" Component_="WpfMaiTouchEmulator.dll"/>
|
||||
<ROW Feature_="MainFeature" Component_="WpfMaiTouchEmulator.exe"/>
|
||||
<ROW Feature_="MainFeature" Component_="Wpf.Ui.dll"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiIconsComponent">
|
||||
<ROW Name="icon.exe" SourcePath="..\Assets\icon.ico" Index="0"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiInstExSeqComponent">
|
||||
<ROW Action="AI_DOWNGRADE" Condition="AI_NEWERPRODUCTFOUND AND (UILevel <> 5)" Sequence="210"/>
|
||||
<ROW Action="AI_RESTORE_LOCATION" Condition="APPDIR=""" Sequence="749"/>
|
||||
<ROW Action="AI_STORE_LOCATION" Condition="(Not Installed) OR REINSTALL" Sequence="1501"/>
|
||||
<ROW Action="AI_PREPARE_UPGRADE" Condition="AI_UPGRADE="No" AND (Not Installed)" Sequence="1399"/>
|
||||
<ROW Action="AI_ResolveKnownFolders" Sequence="52"/>
|
||||
<ROW Action="AI_EnableDebugLog" Sequence="51"/>
|
||||
<ROW Action="AI_DetectSoftware" Sequence="101"/>
|
||||
<ROW Action="AI_SETMIXINSTLOCATION" Sequence="748"/>
|
||||
<ROW Action="AI_PrepareShortcutFlags" Condition="(VersionNT > 501) AND ((NOT Installed) OR (Installed AND (REMOVE<>"ALL") AND (AI_INSTALL_MODE<>"Remove")))" Sequence="4501"/>
|
||||
<ROW Action="AI_PinShortcuts" Condition="(VersionNT > 600) AND ((NOT Installed) OR (Installed AND (REMOVE<>"ALL") AND (AI_INSTALL_MODE<>"Remove")))" Sequence="6499"/>
|
||||
<ROW Action="AI_UnpinShortcuts" Condition="(VersionNT > 600) AND (REMOVE = "ALL")" Sequence="3199"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiInstallUISequenceComponent">
|
||||
<ROW Action="AI_PRESERVE_INSTALL_TYPE" Sequence="199"/>
|
||||
<ROW Action="AI_RESTORE_LOCATION" Condition="APPDIR=""" Sequence="749"/>
|
||||
<ROW Action="AI_ResolveKnownFolders" Sequence="53"/>
|
||||
<ROW Action="AI_DpiContentScale" Sequence="52"/>
|
||||
<ROW Action="AI_EnableDebugLog" Sequence="51"/>
|
||||
<ROW Action="AI_DetectSoftware" Sequence="101"/>
|
||||
<ROW Action="AI_SETMIXINSTLOCATION" Sequence="748"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiLaunchConditionsComponent">
|
||||
<ROW Condition="( Version9X OR ( NOT VersionNT64 ) OR ( VersionNT64 AND ((VersionNT64 <> 601) OR (MsiNTProductType <> 1)) AND ((VersionNT64 <> 601) OR (MsiNTProductType = 1)) AND ((VersionNT64 <> 602) OR (MsiNTProductType <> 1)) AND ((VersionNT64 <> 602) OR (MsiNTProductType = 1)) AND ((VersionNT64 <> 603) OR (MsiNTProductType <> 1)) AND ((VersionNT64 <> 603) OR (MsiNTProductType = 1)) AND ((VersionNT64 <> 1000) OR (MsiNTProductType = 1)) ) )" Description="[ProductName] cannot be installed on the following Windows versions: [WindowsTypeNT64Display]." DescriptionLocId="AI.LaunchCondition.NoSpecificNT64" IsPredefined="true" Builds="DefaultBuild"/>
|
||||
<ROW Condition="( Version9X OR VersionNT64 OR ( VersionNT AND (VersionNT <> 601) AND (VersionNT <> 602) AND (VersionNT <> 603) ) )" Description="[ProductName] cannot be installed on the following Windows versions: [WindowsTypeNTDisplay]." DescriptionLocId="AI.LaunchCondition.NoSpecificNT" IsPredefined="true" Builds="DefaultBuild"/>
|
||||
<ROW Condition="((VersionNT <> 501) AND (VersionNT <> 502))" Description="[ProductName] cannot be installed on [WindowsTypeNT5XDisplay]." DescriptionLocId="AI.LaunchCondition.NoNT5X" IsPredefined="true" Builds="DefaultBuild"/>
|
||||
<ROW Condition="(VersionNT <> 400)" Description="[ProductName] cannot be installed on [WindowsTypeNT40Display]." DescriptionLocId="AI.LaunchCondition.NoNT40" IsPredefined="true" Builds="DefaultBuild"/>
|
||||
<ROW Condition="(VersionNT <> 500)" Description="[ProductName] cannot be installed on [WindowsTypeNT50Display]." DescriptionLocId="AI.LaunchCondition.NoNT50" IsPredefined="true" Builds="DefaultBuild"/>
|
||||
<ROW Condition="(VersionNT <> 600)" Description="[ProductName] cannot be installed on [WindowsTypeNT60Display]." DescriptionLocId="AI.LaunchCondition.NoNT60" IsPredefined="true" Builds="DefaultBuild"/>
|
||||
<ROW Condition="AI_DETECTED_DOTNET_CORE_VERSION >= AI_REQUIRED_DOTNET_CORE_VERSION" Description="[ProductName] cannot be installed on systems with .NET Core version lower than [AI_REQUIRED_DOTNET_CORE_DISPLAY]." DescriptionLocId="AI.LaunchCondition.DotNETCore" IsPredefined="true" Builds="DefaultBuild"/>
|
||||
<ROW Condition="VersionNT" Description="[ProductName] cannot be installed on [WindowsType9XDisplay]." DescriptionLocId="AI.LaunchCondition.No9X" IsPredefined="true" Builds="DefaultBuild"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiRegLocatorComponent">
|
||||
<ROW Signature_="AI_INSTALLPERUSER" Root="2" Key="Software\[Manufacturer]\[UpgradeCode]" Name="AI_INSTALLPERUSER" Type="2"/>
|
||||
<ROW Signature_="AI_INSTALLPERUSER_1" Root="1" Key="Software\[Manufacturer]\[UpgradeCode]" Name="AI_INSTALLPERUSER" Type="2"/>
|
||||
<ROW Signature_="AI_INSTALLPERUSER_2" Root="2" Key="Software\[Manufacturer]\[UpgradeCode]" Name="AI_INSTALLPERUSER" Type="18"/>
|
||||
<ROW Signature_="AI_INSTALLPERUSER_3" Root="1" Key="Software\[Manufacturer]\[UpgradeCode]" Name="AI_INSTALLPERUSER" Type="18"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiRegsComponent">
|
||||
<ROW Registry="AI_INSTALLPERUSER" Root="-1" Key="Software\[Manufacturer]\[UpgradeCode]" Name="AI_INSTALLPERUSER" Value="[AI_INSTALLPERUSER]" Component_="AI_INSTALLPERUSER"/>
|
||||
<ROW Registry="Manufacturer" Root="-1" Key="Software\[Manufacturer]" Name="\"/>
|
||||
<ROW Registry="Path" Root="-1" Key="Software\[Manufacturer]\[ProductName]" Name="Path" Value="[APPDIR]" Component_="ProductInformation"/>
|
||||
<ROW Registry="ProductName" Root="-1" Key="Software\[Manufacturer]\[ProductName]" Name="\"/>
|
||||
<ROW Registry="Software" Root="-1" Key="Software" Name="\"/>
|
||||
<ROW Registry="UpgradeCode" Root="-1" Key="Software\[Manufacturer]\[UpgradeCode]" Name="\"/>
|
||||
<ROW Registry="Version" Root="-1" Key="Software\[Manufacturer]\[ProductName]" Name="Version" Value="[ProductVersion]" Component_="ProductInformation"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiShortsComponent">
|
||||
<ROW Shortcut="WpfMaiTouchEmulator" Directory_="ProgramMenuFolder" Name="MAITOU~1|Mai Touch Emulator" Component_="WpfMaiTouchEmulator.exe" Target="[#WpfMaiTouchEmulator.exe]" Hotkey="0" Icon_="icon.exe" IconIndex="0" ShowCmd="1" WkDir="APPDIR" CustomFlags="2"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiThemeComponent">
|
||||
<ATTRIBUTE name="UsedTheme" value="classic"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiUpgradeComponent">
|
||||
<ROW UpgradeCode="[|UpgradeCode]" VersionMin="0.0.1" VersionMax="[|ProductVersion]" Attributes="257" ActionProperty="OLDPRODUCTS"/>
|
||||
<ROW UpgradeCode="[|UpgradeCode]" VersionMin="[|ProductVersion]" Attributes="2" ActionProperty="AI_NEWERPRODUCTFOUND"/>
|
||||
</COMPONENT>
|
||||
</DOCUMENT>
|
|
@ -3,7 +3,7 @@ using System.Runtime.InteropServices;
|
|||
using System.IO;
|
||||
using System.Diagnostics;
|
||||
|
||||
class DumpCreator
|
||||
public class DumpCreator
|
||||
{
|
||||
[Flags]
|
||||
public enum Typ : uint
|
|
@ -7,12 +7,22 @@ public static class Logger
|
|||
private static readonly object lockObj = new();
|
||||
private static string? logFilePath;
|
||||
|
||||
public static string GetLogPath()
|
||||
{
|
||||
var path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "WpfMaiTouchEmulator");
|
||||
if (!Directory.Exists(path))
|
||||
{
|
||||
Directory.CreateDirectory(path);
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
private static string GetLogFilePath()
|
||||
{
|
||||
if (logFilePath == null)
|
||||
{
|
||||
var fileName = $"app_{DateTime.Now:yyyy-MM-dd}.log";
|
||||
logFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, fileName);
|
||||
logFilePath = Path.Combine(GetLogPath(), fileName);
|
||||
}
|
||||
return logFilePath;
|
||||
}
|
||||
|
@ -21,7 +31,7 @@ public static class Logger
|
|||
public static void CleanupOldLogFiles()
|
||||
{
|
||||
var directory = new DirectoryInfo(AppDomain.CurrentDomain.BaseDirectory);
|
||||
var oldFiles = directory.GetFiles("app_*.log")
|
||||
var oldFiles = new DirectoryInfo(GetLogPath()).GetFiles("app_*.log")
|
||||
.Where(f => f.CreationTime < DateTime.Now.AddDays(-7))
|
||||
.ToList();
|
||||
|
174
MainWindow.xaml
174
MainWindow.xaml
|
@ -3,52 +3,140 @@
|
|||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
|
||||
mc:Ignorable="d"
|
||||
Closing="MainWindow_Closing"
|
||||
Title="MainWindow" Height="360" Width="500" ResizeMode="NoResize" WindowStartupLocation="CenterScreen">
|
||||
<StackPanel VerticalAlignment="Top">
|
||||
<Menu Width="Auto" Height="20">
|
||||
<MenuItem Header="{Binding LbMenuCategoryHelp}" d:Header="_Help">
|
||||
<MenuItem x:Name="instructionsLabel" Header="{Binding LbMenuItemSetup}" HorizontalAlignment="Left" Width="220" Click="instructionsLabel_Click"/>
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
<Grid Background="Transparent" Height="317" VerticalAlignment="Top" >
|
||||
<Button x:Name="ConnectToPortButton" Content="{Binding LbConnectToPort}" d:Content="Connect to port" HorizontalAlignment="Left" Margin="10,95,0,0" VerticalAlignment="Top" Click="ConnectToPortButton_Click" Width="130" />
|
||||
<TextBox x:Name="RecievedLogBox"
|
||||
IsReadOnly="True"
|
||||
HorizontalScrollBarVisibility="Disabled"
|
||||
VerticalScrollBarVisibility="Auto"
|
||||
AcceptsReturn="True"
|
||||
AcceptsTab="True"
|
||||
TextWrapping="Wrap" Margin="376,34,0,219" HorizontalAlignment="Left" Width="88" />
|
||||
<TextBox x:Name="SentLogBox"
|
||||
IsReadOnly="True"
|
||||
HorizontalScrollBarVisibility="Disabled"
|
||||
VerticalScrollBarVisibility="Auto"
|
||||
AcceptsReturn="True"
|
||||
AcceptsTab="True"
|
||||
TextWrapping="Wrap" Margin="376,121,0,129" HorizontalAlignment="Left" Width="88" />
|
||||
<Label x:Name="label" Content="{Binding LbRecievedData}" d:Content="Recieved Data" HorizontalAlignment="Left" Margin="376,8,0,0" VerticalAlignment="Top" Width="88"/>
|
||||
<Label x:Name="label_Copy" Content="{Binding LbSentData}" d:Content="Sent Data" HorizontalAlignment="Left" Margin="376,95,0,0" VerticalAlignment="Top" Width="88"/>
|
||||
<Label x:Name="label_Copy1" Content="{Binding LbButtonState}" d:Content="Button state" HorizontalAlignment="Left" Margin="238,56,0,0" VerticalAlignment="Top" Width="88"/>
|
||||
<Label x:Name="buttonStateValue" Content="0" HorizontalAlignment="Left" Margin="238,82,0,0" VerticalAlignment="Top" RenderTransformOrigin="3.566,1.468" FontSize="10"/>
|
||||
<CheckBox x:Name="debugMode" Content="{Binding LbDebugMode}" d:Content="Debug mode" HorizontalAlignment="Left" Margin="10,213,0,0" VerticalAlignment="Top" IsChecked="{Binding Path=IsDebugEnabled}" Click="debugMode_Click" Cursor="" Focusable="False" ToolTip="Show the touchpad with translucency and show inputs highlighted" Width="224"/>
|
||||
<CheckBox x:Name="automaticTouchPanelPositioning" d:Content="Automatic touch panel positioning" HorizontalAlignment="Left" Margin="10,233,0,0" VerticalAlignment="Top" Height="17" Width="224" Content="{Binding LbAutoSensorPositioning}" IsChecked="{Binding Path=IsAutomaticPositioningEnabled}" Click="automaticTouchPanelPositioning_Click" ToolTip="{Binding LbAutoSensorPositioningTT}"/>
|
||||
<CheckBox x:Name="automaticPortConnecting" d:Content="Automatic port connecting" HorizontalAlignment="Left" Margin="10,255,0,0" VerticalAlignment="Top" Height="17" Width="224" Content="{Binding LbAutoPortConnecting}" IsChecked="{Binding Path=IsAutomaticPortConnectingEnabled}" Click="automaticPortConnecting_Click" ToolTip="{Binding LbAutoPortConnectingTT}"/>
|
||||
<Label x:Name="label1" Content="{Binding LbConnectionState}" d:Content="Connection state" HorizontalAlignment="Left" Margin="238,8,0,0" VerticalAlignment="Top"/>
|
||||
<Label x:Name="connectionStateLabel" Content="{Binding LbConnectionStateNotConnected}" d:Content="Not connected" HorizontalAlignment="Left" Margin="238,31,0,0" VerticalAlignment="Top" FontSize="10"/>
|
||||
<CheckBox x:Name="exitWithSinmai" Content="{Binding LbExitWithSinmai}" d:Content="Exit with Sinmai" HorizontalAlignment="Left" Margin="10,277,0,0" VerticalAlignment="Top" Height="17" Width="224" IsChecked="{Binding IsExitWithSinmaiEnabled}" Click="exitWithSinmai_Click" ToolTip="{Binding LbExitWithSinmaiTT}"/>
|
||||
<Button x:Name="buttonInstallComPort" Content="{Binding LbInstallComPort}" d:Content="Install COM port" HorizontalAlignment="Left" Margin="10,9,0,0" VerticalAlignment="Top" Click="buttonInstallComPort_Click" Width="130"/>
|
||||
<Button x:Name="buttonUninstallComPorts" Content="{Binding LbUninstallComPort}" d:Content="Uninstall COM port" HorizontalAlignment="Left" Margin="10,34,0,0" VerticalAlignment="Top" Click="buttonUninstallComPorts_Click" Width="130"/>
|
||||
<Button x:Name="buttonListComPorts" Content="{Binding LbListComPorts}" d:Content="List installed COM ports" HorizontalAlignment="Left" Margin="10,59,0,0" VerticalAlignment="Top" Click="buttonListComPorts_Click" Width="130"/>
|
||||
<Separator HorizontalAlignment="Left" Margin="10,84,0,0" VerticalAlignment="Top" Height="6" Width="126"/>
|
||||
<ComboBox x:Name="languageSelector" HorizontalAlignment="Left" Margin="10,186,0,0" VerticalAlignment="Top" Width="149" ItemsSource="{Binding SupportedLanguages}"
|
||||
DisplayMemberPath="NativeName"
|
||||
SelectedItem="{Binding SelectedLanguage, Mode=TwoWay}"/>
|
||||
<Label x:Name="lagnuageLabel" Content="{Binding LbLanguageDropdown}" d:Content="Language" HorizontalAlignment="Left" Margin="10,155,0,0" VerticalAlignment="Top" Width="126"/>
|
||||
Background="AliceBlue"
|
||||
Title="MainWindow" Height="700" Width="500" WindowStartupLocation="CenterScreen">
|
||||
<ScrollViewer>
|
||||
<StackPanel MaxWidth="400" Margin="0,0,0,50">
|
||||
<Menu>
|
||||
<MenuItem Header="{Binding LbMenuCategoryHelp}" d:Header="_Help">
|
||||
<MenuItem.Icon>
|
||||
<ui:SymbolIcon Symbol="BookQuestionMark20" />
|
||||
</MenuItem.Icon>
|
||||
<MenuItem x:Name="instructionsLabel" Header="{Binding LbMenuItemSetup}" Click="instructionsLabel_Click"/>
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
<ui:Card Margin="0,0,0,10">
|
||||
<StackPanel>
|
||||
<ui:TextBlock d:Text="Connection State" Text="{Binding LbConnectionState}"/>
|
||||
<Label x:Name="connectionStateLabel" Content="{Binding LbConnectionStateNotConnected}" d:Content="Not connected" FontSize="10"/>
|
||||
<Separator Margin="0,6"/>
|
||||
<Label x:Name="recievedDataLabel" Content="{Binding LbRecievedData}" d:Content="Recieved Data"/>
|
||||
<ui:TextBox x:Name="RecievedLogBox"
|
||||
IsReadOnly="True"
|
||||
HorizontalScrollBarVisibility="Disabled"
|
||||
VerticalScrollBarVisibility="Auto"
|
||||
Focusable="False"
|
||||
AcceptsReturn="True"
|
||||
AcceptsTab="True"
|
||||
TextWrapping="Wrap" Height="80">
|
||||
<ui:TextBox.Icon>
|
||||
<ui:SymbolIcon Symbol="ArrowDownLeft20" />
|
||||
</ui:TextBox.Icon>
|
||||
</ui:TextBox>
|
||||
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
<Label x:Name="sentDataLabel" Content="{Binding LbSentData}" d:Content="Sent Data"/>
|
||||
<ui:TextBox x:Name="SentLogBox"
|
||||
IsReadOnly="True"
|
||||
Focusable="False"
|
||||
HorizontalScrollBarVisibility="Disabled"
|
||||
VerticalScrollBarVisibility="Auto"
|
||||
AcceptsReturn="True"
|
||||
AcceptsTab="True"
|
||||
TextWrapping="Wrap" Height="80">
|
||||
<ui:TextBox.Icon>
|
||||
<ui:SymbolIcon Symbol="ArrowUpRight20" />
|
||||
</ui:TextBox.Icon>
|
||||
</ui:TextBox>
|
||||
<Separator Margin="0,6"/>
|
||||
<Label x:Name="buttonStateLabel" Content="{Binding LbButtonState}" d:Content="Button state" />
|
||||
<Label x:Name="buttonStateValue" Content="0" />
|
||||
</StackPanel>
|
||||
</ui:Card>
|
||||
<ui:CardExpander
|
||||
CornerRadius="8"
|
||||
Margin="0,0,0,10"
|
||||
Header="{Binding LbComPort}"
|
||||
d:Header="COM Port">
|
||||
<ui:CardExpander.Icon>
|
||||
<ui:SymbolIcon Symbol="PlugDisconnected20" />
|
||||
</ui:CardExpander.Icon>
|
||||
<StackPanel>
|
||||
<ui:Button x:Name="ConnectToPortButton" Content="{Binding LbConnectToPort}" d:Content="Connect to port" Click="ConnectToPortButton_Click" />
|
||||
<Separator Margin="0,6"/>
|
||||
<ui:Button x:Name="buttonInstallComPort" Content="{Binding LbInstallComPort}" Margin="0,0,0,10" d:Content="Install COM port" Click="buttonInstallComPort_Click" />
|
||||
<ui:Button x:Name="buttonUninstallComPorts" Content="{Binding LbUninstallComPort}" Margin="0,0,0,10" d:Content="Uninstall COM port" Click="buttonUninstallComPorts_Click" />
|
||||
<ui:Button x:Name="buttonListComPorts" Content="{Binding LbListComPorts}" d:Content="List installed COM ports" Click="buttonListComPorts_Click" />
|
||||
</StackPanel>
|
||||
</ui:CardExpander>
|
||||
<ui:CardExpander
|
||||
CornerRadius="8"
|
||||
Margin="0,0,0,10"
|
||||
Header="{Binding LbBorderSettings}"
|
||||
d:Header="Border settings">
|
||||
<ui:CardExpander.Icon>
|
||||
<ui:SymbolIcon Symbol="EditSettings20" />
|
||||
</ui:CardExpander.Icon>
|
||||
<StackPanel>
|
||||
<RadioButton x:Name="rbBorderDisabled" Content="{Binding LbBorderDisabled}" d:Content="Disabled" GroupName="ColorOptions" Checked="RadioButton1_Checked"/>
|
||||
<RadioButton x:Name="rbBorderSolidColour" Content="{Binding LbBorderSolid}" d:Content="Solid Colour" GroupName="ColorOptions" Checked="RadioButton2_Checked"/>
|
||||
<ui:TextBox x:Name="txtBorderHexColor" Text="{Binding Path=BorderColour}" PlaceholderText="#AARRGGBB" IsEnabled="False" Margin="10,10,0,10" TextChanged="txtBorderHexColor_TextChanged"/>
|
||||
|
||||
<RadioButton Name="rbBorderRainbow" Content="{Binding LbBorderRainbow}" d:Content="Rainbow" GroupName="ColorOptions" Checked="RadioButton3_Checked"/>
|
||||
</StackPanel>
|
||||
</ui:CardExpander>
|
||||
<ui:CardExpander
|
||||
CornerRadius="8"
|
||||
Margin="0,0,0,10"
|
||||
Header="{Binding LbSettings}"
|
||||
d:Header="Settings">
|
||||
<ui:CardExpander.Icon>
|
||||
<ui:SymbolIcon Symbol="Settings20" />
|
||||
</ui:CardExpander.Icon>
|
||||
<StackPanel>
|
||||
<Label x:Name="languageLabel" Content="{Binding LbLanguageDropdown}" d:Content="Language"/>
|
||||
<ComboBox x:Name="languageSelector" ItemsSource="{Binding SupportedLanguages}" DisplayMemberPath="NativeName" SelectedItem="{Binding SelectedLanguage, Mode=TwoWay}"/>
|
||||
<Separator Margin="0,6"/>
|
||||
<CheckBox x:Name="largeButtons" Content="{Binding LbLargeButtons}" d:Content="LargeButtons" IsChecked="{Binding Path=IsLargeButtonsEnabled}" Click="largeButtons_Click" Cursor="" Focusable="False" ToolTip="{Binding LbLargeButtonsTT}" />
|
||||
<CheckBox x:Name="debugMode" Content="{Binding LbDebugMode}" d:Content="Debug mode" IsChecked="{Binding Path=IsDebugEnabled}" Click="debugMode_Click" Cursor="" Focusable="False" ToolTip="{Binding LbDebugModeTT}" />
|
||||
<CheckBox x:Name="automaticTouchPanelPositioning" d:Content="Automatic touch panel positioning" Content="{Binding LbAutoSensorPositioning}" IsChecked="{Binding Path=IsAutomaticPositioningEnabled}" Click="automaticTouchPanelPositioning_Click" ToolTip="{Binding LbAutoSensorPositioningTT}"/>
|
||||
<CheckBox x:Name="automaticPortConnecting" d:Content="Automatic port connecting" Content="{Binding LbAutoPortConnecting}" IsChecked="{Binding Path=IsAutomaticPortConnectingEnabled}" Click="automaticPortConnecting_Click" ToolTip="{Binding LbAutoPortConnectingTT}"/>
|
||||
<CheckBox x:Name="exitWithSinmai" Content="{Binding LbExitWithSinmai}" d:Content="Exit with Sinmai" IsChecked="{Binding IsExitWithSinmaiEnabled}" Click="exitWithSinmai_Click" ToolTip="{Binding LbExitWithSinmaiTT}"/>
|
||||
<CheckBox x:Name="emulateRingButtons" Content="{Binding LbEmulateRingButtons}" d:Content="Emulate ring buttons" IsChecked="{Binding IsRingButtonEmulationEnabled}" ToolTip="{Binding LbEmulateRingButtonsTT}" Click="emulateRingButtons_Click"/>
|
||||
<ui:Button x:Name="openLogFolderButton" Content="{Binding LbOpenLogFolder}" d:Content="Open log folder" Click="openLogFolderButton_Click" />
|
||||
</StackPanel>
|
||||
</ui:CardExpander>
|
||||
<ui:Card>
|
||||
<StackPanel>
|
||||
<TextBlock Text="{Binding LbAbout}" d:Text="About" Margin="0,0,0,10"/>
|
||||
<ui:Anchor
|
||||
Margin="0"
|
||||
Padding="16"
|
||||
HorizontalAlignment="Stretch"
|
||||
HorizontalContentAlignment="Stretch"
|
||||
Background="Transparent"
|
||||
BorderThickness="0,1,0,0"
|
||||
CornerRadius="0"
|
||||
NavigateUri="https://github.com/Leapward-Koex/MaiTouchSensorEmulator">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0" Text="Github" />
|
||||
<ui:SymbolIcon Grid.Column="1" Symbol="WindowNew20" />
|
||||
</Grid>
|
||||
</ui:Anchor>
|
||||
<Label Content="{Binding LbAppVersion}" d:Content="1.0.0.0"/>
|
||||
<Label Content="By Leapward-Koex"/>
|
||||
</StackPanel>
|
||||
|
||||
</ui:Card>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
|
||||
|
||||
|
||||
</Window>
|
||||
|
|
|
@ -1,26 +1,42 @@
|
|||
using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
using System.Windows;
|
||||
using WpfMaiTouchEmulator.Managers;
|
||||
|
||||
namespace WpfMaiTouchEmulator;
|
||||
|
||||
public enum BorderSetting
|
||||
{
|
||||
Disabled,
|
||||
Solid,
|
||||
Rainbow
|
||||
}
|
||||
|
||||
public partial class MainWindow : Window
|
||||
{
|
||||
private readonly MaiTouchSensorButtonStateManager buttonState;
|
||||
private readonly MaiTouchComConnector connector;
|
||||
private readonly VirtualComPortManager comPortManager;
|
||||
private TouchPanel _touchPanel;
|
||||
private TouchPanel? _touchPanel;
|
||||
|
||||
public MainWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
CheckForUserSettingsUpgrade();
|
||||
DataContext = new MainWindowViewModel()
|
||||
{
|
||||
IsDebugEnabled = Properties.Settings.Default.IsDebugEnabled,
|
||||
IsAutomaticPortConnectingEnabled = Properties.Settings.Default.IsAutomaticPortConnectingEnabled,
|
||||
IsAutomaticPositioningEnabled = Properties.Settings.Default.IsAutomaticPositioningEnabled,
|
||||
IsExitWithSinmaiEnabled = Properties.Settings.Default.IsExitWithSinmaiEnabled,
|
||||
IsRingButtonEmulationEnabled = Properties.Settings.Default.IsRingButtonEmulationEnabled,
|
||||
IsLargeButtonsEnabled = Properties.Settings.Default.IsLargeButtonsEnabled,
|
||||
BorderColour = Properties.Settings.Default.BorderColour,
|
||||
LbAppVersion = Assembly.GetEntryAssembly()?.GetName().Version?.ToString() ?? "1.0.0.0",
|
||||
};
|
||||
|
||||
LoadBorderRadioButtonSetting();
|
||||
|
||||
Title = "Mai Touch Emulator";
|
||||
buttonState = new MaiTouchSensorButtonStateManager(buttonStateValue);
|
||||
connector = new MaiTouchComConnector(buttonState, (MainWindowViewModel)DataContext);
|
||||
|
@ -63,17 +79,26 @@ public partial class MainWindow : Window
|
|||
|
||||
|
||||
Loaded += (s, e) => {
|
||||
var dataContext = (MainWindowViewModel)DataContext;
|
||||
|
||||
Logger.Info("Main window loaded, creating touch panel");
|
||||
_touchPanel = new TouchPanel();
|
||||
_touchPanel.onTouch = (value) => { buttonState.PressButton(value); };
|
||||
_touchPanel.onRelease = (value) => { buttonState.ReleaseButton(value); };
|
||||
_touchPanel.onTouch = (value) => {
|
||||
buttonState.PressButton(value);
|
||||
connector.SendTouchscreenState();
|
||||
};
|
||||
_touchPanel.onRelease = (value) => {
|
||||
buttonState.ReleaseButton(value);
|
||||
connector.SendTouchscreenState();
|
||||
};
|
||||
_touchPanel.onInitialReposition = () => { WindowState = WindowState.Minimized; };
|
||||
_touchPanel.SetBorderMode((BorderSetting)Properties.Settings.Default.BorderSetting, dataContext.BorderColour);
|
||||
_touchPanel.Show();
|
||||
_touchPanel.Owner = this;
|
||||
|
||||
var dataContext = (MainWindowViewModel)DataContext;
|
||||
_touchPanel.DataContext = dataContext;
|
||||
|
||||
_touchPanel.SetDebugMode(dataContext.IsDebugEnabled);
|
||||
_touchPanel.SetLargeButtonMode(dataContext.IsLargeButtonsEnabled);
|
||||
if (Properties.Settings.Default.IsAutomaticPositioningEnabled)
|
||||
{
|
||||
_touchPanel.DragWindowHandle.Visibility = Visibility.Hidden;
|
||||
|
@ -89,12 +114,10 @@ public partial class MainWindow : Window
|
|||
{
|
||||
e.Cancel = true;
|
||||
await connector.Disconnect();
|
||||
foreach (Window childWindow in OwnedWindows)
|
||||
{
|
||||
childWindow.Close();
|
||||
}
|
||||
_touchPanel?.Close();
|
||||
Closing -= MainWindow_Closing;
|
||||
e.Cancel = false;
|
||||
Application.Current.Shutdown();
|
||||
}
|
||||
|
||||
private async void ExitWithSinmaiLoop()
|
||||
|
@ -140,6 +163,18 @@ public partial class MainWindow : Window
|
|||
}
|
||||
}
|
||||
|
||||
private static void CheckForUserSettingsUpgrade()
|
||||
{
|
||||
if (!Properties.Settings.Default.UserSettingsUpgradeRequired)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Properties.Settings.Default.Upgrade();
|
||||
Properties.Settings.Default.UserSettingsUpgradeRequired = false;
|
||||
Properties.Settings.Default.Save();
|
||||
}
|
||||
|
||||
private void ShowSetupInstructionsDialog()
|
||||
{
|
||||
var dataContext = (MainWindowViewModel)DataContext;
|
||||
|
@ -153,7 +188,7 @@ public partial class MainWindow : Window
|
|||
{
|
||||
if (dataContext.IsAutomaticPositioningEnabled)
|
||||
{
|
||||
_touchPanel.PositionTouchPanel();
|
||||
_touchPanel?.PositionTouchPanel();
|
||||
}
|
||||
|
||||
await Task.Delay(1000);
|
||||
|
@ -167,16 +202,16 @@ public partial class MainWindow : Window
|
|||
{
|
||||
if (dataContext.IsAutomaticPortConnectingEnabled)
|
||||
{
|
||||
await connector.StartTouchSensorPolling();
|
||||
connector.StartTouchSensorPolling();
|
||||
}
|
||||
await Task.Delay(1000);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private async void ConnectToPortButton_Click(object sender, RoutedEventArgs e)
|
||||
private void ConnectToPortButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
await connector.StartTouchSensorPolling();
|
||||
connector.StartTouchSensorPolling();
|
||||
}
|
||||
|
||||
private void debugMode_Click(object sender, RoutedEventArgs e)
|
||||
|
@ -186,7 +221,17 @@ public partial class MainWindow : Window
|
|||
dataContext.IsDebugEnabled = !enabled;
|
||||
Properties.Settings.Default.IsDebugEnabled = dataContext.IsDebugEnabled;
|
||||
Properties.Settings.Default.Save();
|
||||
_touchPanel.SetDebugMode(dataContext.IsDebugEnabled);
|
||||
_touchPanel?.SetDebugMode(dataContext.IsDebugEnabled);
|
||||
}
|
||||
|
||||
private void largeButtons_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var dataContext = (MainWindowViewModel)DataContext;
|
||||
var enabled = !dataContext.IsLargeButtonsEnabled;
|
||||
dataContext.IsLargeButtonsEnabled = !enabled;
|
||||
Properties.Settings.Default.IsLargeButtonsEnabled = dataContext.IsLargeButtonsEnabled;
|
||||
Properties.Settings.Default.Save();
|
||||
_touchPanel?.SetLargeButtonMode(dataContext.IsLargeButtonsEnabled);
|
||||
}
|
||||
|
||||
private void automaticTouchPanelPositioning_Click(object sender, RoutedEventArgs e)
|
||||
|
@ -241,4 +286,68 @@ public partial class MainWindow : Window
|
|||
{
|
||||
ShowSetupInstructionsDialog();
|
||||
}
|
||||
|
||||
private void emulateRingButtons_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var dataContext = (MainWindowViewModel)DataContext;
|
||||
var enabled = !dataContext.IsRingButtonEmulationEnabled;
|
||||
dataContext.IsRingButtonEmulationEnabled = !enabled;
|
||||
Properties.Settings.Default.IsRingButtonEmulationEnabled = dataContext.IsRingButtonEmulationEnabled;
|
||||
Properties.Settings.Default.Save();
|
||||
_touchPanel?.SetEmulateRingButton(dataContext.IsRingButtonEmulationEnabled);
|
||||
}
|
||||
|
||||
private void LoadBorderRadioButtonSetting()
|
||||
{
|
||||
rbBorderDisabled.IsChecked = Properties.Settings.Default.BorderSetting == (int)BorderSetting.Disabled;
|
||||
txtBorderHexColor.IsEnabled = Properties.Settings.Default.BorderSetting == (int)BorderSetting.Solid;
|
||||
rbBorderSolidColour.IsChecked = Properties.Settings.Default.BorderSetting == (int)BorderSetting.Solid;
|
||||
rbBorderRainbow.IsChecked = Properties.Settings.Default.BorderSetting == (int)BorderSetting.Rainbow;
|
||||
}
|
||||
|
||||
private void RadioButton1_Checked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
txtBorderHexColor.IsEnabled = false;
|
||||
Properties.Settings.Default.BorderSetting = (int)BorderSetting.Disabled;
|
||||
Properties.Settings.Default.Save();
|
||||
|
||||
_touchPanel?.SetBorderMode(BorderSetting.Disabled, "");
|
||||
}
|
||||
|
||||
private void RadioButton2_Checked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
txtBorderHexColor.IsEnabled = true;
|
||||
Properties.Settings.Default.BorderSetting = (int)BorderSetting.Solid;
|
||||
|
||||
Properties.Settings.Default.Save();
|
||||
|
||||
_touchPanel?.SetBorderMode(BorderSetting.Solid, Properties.Settings.Default.BorderColour);
|
||||
}
|
||||
|
||||
private void RadioButton3_Checked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
txtBorderHexColor.IsEnabled = false;
|
||||
Properties.Settings.Default.BorderSetting = (int)BorderSetting.Rainbow;
|
||||
|
||||
Properties.Settings.Default.Save();
|
||||
|
||||
_touchPanel?.SetBorderMode(BorderSetting.Rainbow, "");
|
||||
}
|
||||
|
||||
private void txtBorderHexColor_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e)
|
||||
{
|
||||
var textWithoutHash = txtBorderHexColor.Text.TrimStart('#') ?? "";
|
||||
if (textWithoutHash.Length == 6 || textWithoutHash.Length == 8)
|
||||
{
|
||||
var textWithHash = "#" + textWithoutHash;
|
||||
Properties.Settings.Default.BorderColour = textWithHash;
|
||||
Properties.Settings.Default.Save();
|
||||
_touchPanel?.SetBorderMode(BorderSetting.Solid, textWithHash);
|
||||
}
|
||||
}
|
||||
|
||||
private void openLogFolderButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Process.Start("explorer.exe", Logger.GetLogPath());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,64 +8,112 @@ namespace WpfMaiTouchEmulator;
|
|||
public class MainWindowViewModel : INotifyPropertyChanged
|
||||
{
|
||||
// Language
|
||||
public string LbAutoPortConnecting
|
||||
public string? LbAutoPortConnecting
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public string LbAutoSensorPositioning
|
||||
public string? LbAutoSensorPositioning
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public string LbButtonState
|
||||
public string? LbButtonState
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public string LbConnectionState
|
||||
public string? LbConnectionState
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public string LbConnectionStateNotConnected
|
||||
public string? LbConnectionStateNotConnected
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public string LbConnectToPort
|
||||
public string? LbConnectToPort
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public string LbDebugMode
|
||||
public string? LbDebugMode
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public string LbExitWithSinmai
|
||||
public string? LbLargeButtons
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public string LbInstallComPort
|
||||
public string? LbLargeButtonsTT
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public string LbLanguageDropdown
|
||||
public string? LbExitWithSinmai
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public string LbListComPorts
|
||||
public string? LbEmulateRingButtons
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public string LbReceivedData
|
||||
public string? LbOpenLogFolder
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public string LbRecievedData
|
||||
public string? LbAppVersion
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public string? LbAbout
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public string? LbInstallComPort
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public string? LbLanguageDropdown
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public string? LbBorderSettings
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public string? LbSettings
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public string? LbComPort
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public string? LbBorderDisabled
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public string? LbBorderSolid
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public string? LbBorderRainbow
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public string? LbListComPorts
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public string? LbReceivedData
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public string? LbRecievedData
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
public string LbSentData
|
||||
public string? LbSentData
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public string LbUninstallComPort
|
||||
public string? LbUninstallComPort
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
@ -164,6 +212,11 @@ public class MainWindowViewModel : INotifyPropertyChanged
|
|||
get;
|
||||
private set;
|
||||
}
|
||||
public string? LbDebugModeTT
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
public string? LbAutoSensorPositioningTT
|
||||
{
|
||||
get;
|
||||
|
@ -174,12 +227,20 @@ public class MainWindowViewModel : INotifyPropertyChanged
|
|||
get;
|
||||
private set;
|
||||
}
|
||||
public string? LbEmulateRingButtonsTT
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
private bool _isAutomaticPortConnectingEnabled;
|
||||
private bool _isDebugEnabled;
|
||||
private bool _isLargeButtonsEnabled;
|
||||
private bool _isAutomaticPositioningEnabled;
|
||||
private bool _isExitWithSinmaiEnabled;
|
||||
private CultureInfo _selectedLanguage;
|
||||
private bool _isRingButtonEmulationEnabled;
|
||||
private string _borderColour;
|
||||
private readonly ResourceManager resourceManager;
|
||||
private readonly CultureInfo cultureInfo;
|
||||
|
||||
|
@ -218,6 +279,16 @@ public class MainWindowViewModel : INotifyPropertyChanged
|
|||
}
|
||||
}
|
||||
|
||||
public bool IsLargeButtonsEnabled
|
||||
{
|
||||
get => _isLargeButtonsEnabled;
|
||||
set
|
||||
{
|
||||
_isLargeButtonsEnabled = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsAutomaticPositioningEnabled
|
||||
{
|
||||
get => _isAutomaticPositioningEnabled;
|
||||
|
@ -248,6 +319,27 @@ public class MainWindowViewModel : INotifyPropertyChanged
|
|||
}
|
||||
}
|
||||
|
||||
public bool IsRingButtonEmulationEnabled
|
||||
{
|
||||
get => _isRingButtonEmulationEnabled;
|
||||
set
|
||||
{
|
||||
_isRingButtonEmulationEnabled = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public string BorderColour
|
||||
{
|
||||
get => _borderColour;
|
||||
set
|
||||
{
|
||||
_borderColour = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public CultureInfo SelectedLanguage
|
||||
{
|
||||
get => _selectedLanguage;
|
||||
|
@ -281,9 +373,23 @@ public class MainWindowViewModel : INotifyPropertyChanged
|
|||
LbConnectionStateNotConnected = resourceManager.GetString("lbConnectionStateNotConnected");
|
||||
LbConnectToPort = resourceManager.GetString("lbConnectToPort");
|
||||
LbDebugMode = resourceManager.GetString("lbDebugMode");
|
||||
LbLargeButtons = resourceManager.GetString("lbLargeButtons");
|
||||
LbLargeButtonsTT = resourceManager.GetString("lbLargeButtonsTT");
|
||||
LbExitWithSinmai = resourceManager.GetString("lbExitWithSinmai");
|
||||
LbEmulateRingButtons = resourceManager.GetString("lbEmulateRingButtons");
|
||||
LbOpenLogFolder = resourceManager.GetString("LbOpenLogFolder");
|
||||
LbAbout = resourceManager.GetString("LbAbout");
|
||||
|
||||
LbInstallComPort = resourceManager.GetString("lbInstallComPort");
|
||||
LbLanguageDropdown = resourceManager.GetString("lbLanguageDropdown");
|
||||
|
||||
LbComPort = resourceManager.GetString("LbComPort");
|
||||
LbBorderSettings = resourceManager.GetString("LbBorderSettings");
|
||||
LbSettings = resourceManager.GetString("LbSettings");
|
||||
LbBorderDisabled = resourceManager.GetString("LbBorderDisabled");
|
||||
LbBorderSolid = resourceManager.GetString("LbBorderSolid");
|
||||
LbBorderRainbow = resourceManager.GetString("LbBorderRainbow");
|
||||
|
||||
LbListComPorts = resourceManager.GetString("lbListComPorts");
|
||||
LbReceivedData = resourceManager.GetString("lbReceivedData");
|
||||
LbRecievedData = resourceManager.GetString("lbRecievedData");
|
||||
|
@ -292,8 +398,10 @@ public class MainWindowViewModel : INotifyPropertyChanged
|
|||
LbMenuCategoryHelp = resourceManager.GetString("lbMenuCategoryHelp");
|
||||
LbMenuItemSetup = resourceManager.GetString("lbMenuItemSetup");
|
||||
LbAutoPortConnectingTT = resourceManager.GetString("lbAutoPortConnectingTT");
|
||||
LbDebugModeTT = resourceManager.GetString("lbDebugModeTT");
|
||||
LbAutoSensorPositioningTT = resourceManager.GetString("lbAutoSensorPositioningTT");
|
||||
LbExitWithSinmaiTT = resourceManager.GetString("lbExitWithSinmaiTT");
|
||||
LbEmulateRingButtonsTT = resourceManager.GetString("lbEmulateRingButtonsTT");
|
||||
LbMenuCategoryHelp = resourceManager.GetString("lbMenuCategoryHelp");
|
||||
LbMenuItemSetup = resourceManager.GetString("lbMenuItemSetup");
|
||||
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
using System.IO.Ports;
|
||||
using System.Windows;
|
||||
|
||||
namespace WpfMaiTouchEmulator;
|
||||
namespace WpfMaiTouchEmulator.Managers;
|
||||
internal class MaiTouchComConnector(MaiTouchSensorButtonStateManager buttonState, MainWindowViewModel viewModel)
|
||||
{
|
||||
private static SerialPort? serialPort;
|
||||
private bool isActiveMode;
|
||||
private bool _isActiveMode;
|
||||
private bool _connected;
|
||||
private CancellationTokenSource? _tokenSource;
|
||||
private Thread? _pollThread;
|
||||
|
@ -34,12 +34,12 @@ internal class MaiTouchComConnector(MaiTouchSensorButtonStateManager buttonState
|
|||
internal set;
|
||||
}
|
||||
|
||||
public async Task StartTouchSensorPolling()
|
||||
public void StartTouchSensorPolling()
|
||||
{
|
||||
if (!_connected && _shouldReconnect)
|
||||
{
|
||||
Logger.Info("Trying to connect to COM port...");
|
||||
var virtualPort = "COM23"; // Adjust as needed
|
||||
var virtualPort = "COM23";
|
||||
try
|
||||
{
|
||||
OnConnectStatusChange?.Invoke(_viewModel.TxtComPortConnecting);
|
||||
|
@ -86,10 +86,10 @@ internal class MaiTouchComConnector(MaiTouchSensorButtonStateManager buttonState
|
|||
{
|
||||
while (!token.IsCancellationRequested)
|
||||
{
|
||||
if (isActiveMode)
|
||||
if (_isActiveMode)
|
||||
{
|
||||
SendTouchscreenState();
|
||||
Thread.Sleep(1);
|
||||
Thread.Sleep(10);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -139,55 +139,60 @@ internal class MaiTouchComConnector(MaiTouchSensorButtonStateManager buttonState
|
|||
void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
|
||||
{
|
||||
var recievedData = serialPort?.ReadExisting();
|
||||
var commands = recievedData?.Split(new[] { '}' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (commands != null)
|
||||
var commands = recievedData?.Split(['}'], StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
if (commands is null)
|
||||
{
|
||||
foreach (var command in commands)
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var command in commands)
|
||||
{
|
||||
var cleanedCommand = command.TrimStart('{');
|
||||
Logger.Info($"Received serial data: '{cleanedCommand}'");
|
||||
OnDataRecieved?.Invoke(cleanedCommand);
|
||||
|
||||
if (cleanedCommand == "STAT")
|
||||
{
|
||||
_isActiveMode = true;
|
||||
}
|
||||
else if (cleanedCommand == "RSET")
|
||||
{
|
||||
var cleanedCommand = command.TrimStart('{');
|
||||
Logger.Info($"Received serial data: {cleanedCommand}");
|
||||
OnDataRecieved?.Invoke(cleanedCommand);
|
||||
|
||||
if (cleanedCommand == "STAT")
|
||||
{
|
||||
isActiveMode = true;
|
||||
}
|
||||
else if (cleanedCommand == "RSET")
|
||||
{
|
||||
}
|
||||
else if (cleanedCommand == "HALT")
|
||||
{
|
||||
_isActiveMode = false;
|
||||
}
|
||||
else if (cleanedCommand.Length >= 4 &&
|
||||
(cleanedCommand[2] == 'r' || cleanedCommand[2] == 'k'))
|
||||
{
|
||||
var leftOrRight = cleanedCommand[0];
|
||||
var sensor = cleanedCommand[1];
|
||||
var ratio = cleanedCommand[3];
|
||||
|
||||
}
|
||||
else if (cleanedCommand == "HALT")
|
||||
{
|
||||
isActiveMode = false;
|
||||
}
|
||||
else if (cleanedCommand[2] == 'r' || cleanedCommand[2] == 'k')
|
||||
{
|
||||
var leftOrRight = cleanedCommand[0];
|
||||
var sensor = cleanedCommand[1];
|
||||
var ratio = cleanedCommand[3];
|
||||
|
||||
var newString = $"({leftOrRight}{sensor}{cleanedCommand[2]}{ratio})";
|
||||
serialPort?.Write(newString);
|
||||
OnDataSent?.Invoke(newString);
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.Warn($"Unhandled serial data command {cleanedCommand}");
|
||||
}
|
||||
var newString = $"({leftOrRight}{sensor}{cleanedCommand[2]}{ratio})";
|
||||
serialPort?.Write(newString);
|
||||
OnDataSent?.Invoke(newString);
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.Warn($"Unhandled serial data command '{cleanedCommand}'");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SendTouchscreenState()
|
||||
public void SendTouchscreenState()
|
||||
{
|
||||
if (_connected)
|
||||
if (_connected && _isActiveMode)
|
||||
{
|
||||
var currentState = _buttonState.GetCurrentState();
|
||||
try
|
||||
{
|
||||
serialPort?.Write(currentState, 0, currentState.Length);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (Properties.Settings.Default.IsDebugEnabled)
|
||||
{
|
||||
Logger.Error("Error when writing to serial port on button update", ex);
|
|
@ -1,9 +1,9 @@
|
|||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace WpfMaiTouchEmulator;
|
||||
namespace WpfMaiTouchEmulator.Managers;
|
||||
|
||||
enum TouchValue: long
|
||||
public enum TouchValue : long
|
||||
{
|
||||
A1 = 1 << 0, // 2^0
|
||||
A2 = 1 << 1, // 2^1
|
||||
|
@ -23,7 +23,6 @@ enum TouchValue: long
|
|||
B8 = 1 << 15, // 2^15
|
||||
C1 = 1 << 16, // 2^16
|
||||
C2 = 1 << 17, // 2^17
|
||||
C3 = C1 | C2, // A special sensor used because center notes are hard to press using a windows touchscreen
|
||||
D1 = 1 << 18, // 2^18
|
||||
D2 = 1 << 19, // 2^19
|
||||
D3 = 1 << 20, // 2^20
|
||||
|
@ -50,24 +49,6 @@ internal class MaiTouchSensorButtonStateManager
|
|||
public MaiTouchSensorButtonStateManager(Label buttonStateValue)
|
||||
{
|
||||
this.buttonStateValue = buttonStateValue;
|
||||
SetupUpdateLoop();
|
||||
}
|
||||
|
||||
private async Task SetupUpdateLoop()
|
||||
{
|
||||
string? lastButtonState = null;
|
||||
while (true)
|
||||
{
|
||||
if (lastButtonState != buttonState.ToString())
|
||||
{
|
||||
lastButtonState = buttonState.ToString();
|
||||
Application.Current.Dispatcher.Invoke(() =>
|
||||
{
|
||||
buttonStateValue.Content = lastButtonState;
|
||||
});
|
||||
}
|
||||
await Task.Delay(16);
|
||||
}
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
|
@ -77,12 +58,22 @@ internal class MaiTouchSensorButtonStateManager
|
|||
|
||||
public void PressButton(TouchValue button)
|
||||
{
|
||||
buttonState |= ((long)button);
|
||||
buttonState |= (long)button;
|
||||
|
||||
Application.Current.Dispatcher.Invoke(() =>
|
||||
{
|
||||
buttonStateValue.Content = buttonState.ToString();
|
||||
});
|
||||
}
|
||||
|
||||
public void ReleaseButton(TouchValue button)
|
||||
{
|
||||
buttonState &= ~((long)button);
|
||||
buttonState &= ~(long)button;
|
||||
|
||||
Application.Current.Dispatcher.Invoke(() =>
|
||||
{
|
||||
buttonStateValue.Content = buttonState.ToString();
|
||||
});
|
||||
}
|
||||
|
||||
public byte[] GetCurrentState()
|
|
@ -0,0 +1,56 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace WpfMaiTouchEmulator.Managers;
|
||||
public partial class RingButtonEmulator
|
||||
{
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, nuint dwExtraInfo);
|
||||
|
||||
private static readonly IDictionary<TouchValue, byte> touchRingMapping = new Dictionary<TouchValue, byte>()
|
||||
{
|
||||
{ TouchValue.A1, 0x57 }, // W
|
||||
{ TouchValue.A2, 0x45 }, // E
|
||||
{ TouchValue.A3, 0x44 }, // D
|
||||
{ TouchValue.A4, 0x43 }, // C
|
||||
{ TouchValue.A5, 0x58 }, // X
|
||||
{ TouchValue.A6, 0x5A }, // Z
|
||||
{ TouchValue.A7, 0x41 }, // A
|
||||
{ TouchValue.A8, 0x51 }, // Q
|
||||
};
|
||||
private const uint KEYEVENTF_KEYUP = 0x0002;
|
||||
|
||||
public static bool HasRingButtonMapping(TouchValue touchValue)
|
||||
{
|
||||
return touchRingMapping.ContainsKey(touchValue);
|
||||
}
|
||||
|
||||
public static void PressButton(TouchValue touchValue)
|
||||
{
|
||||
if (touchRingMapping.TryGetValue(touchValue, out var vk))
|
||||
{
|
||||
keybd_event(vk, 0, 0, nuint.Zero);
|
||||
}
|
||||
}
|
||||
|
||||
public static void ReleaseButton(TouchValue touchValue)
|
||||
{
|
||||
if (touchRingMapping.TryGetValue(touchValue, out var vk))
|
||||
{
|
||||
keybd_event(vk, 0, KEYEVENTF_KEYUP, nuint.Zero);
|
||||
}
|
||||
}
|
||||
|
||||
public static void ReleaseAllButtons()
|
||||
{
|
||||
foreach (var vk in touchRingMapping.Values)
|
||||
{
|
||||
keybd_event(vk, 0, KEYEVENTF_KEYUP, nuint.Zero);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,16 +1,16 @@
|
|||
using System.Runtime.InteropServices;
|
||||
using System.Windows;
|
||||
|
||||
namespace WpfMaiTouchEmulator;
|
||||
namespace WpfMaiTouchEmulator.Managers;
|
||||
|
||||
class TouchPanelPositionManager
|
||||
{
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
static extern IntPtr FindWindow(string? lpClassName, string lpWindowName);
|
||||
static extern nint FindWindow(string? lpClassName, string lpWindowName);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);
|
||||
static extern bool GetWindowRect(nint hWnd, out RECT lpRect);
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct RECT
|
||||
|
@ -29,16 +29,16 @@ class TouchPanelPositionManager
|
|||
try
|
||||
{
|
||||
var hWnd = FindWindow(null, "Sinmai");
|
||||
if (hWnd != IntPtr.Zero)
|
||||
if (hWnd != nint.Zero)
|
||||
{
|
||||
RECT rect;
|
||||
if (GetWindowRect(hWnd, out rect))
|
||||
{
|
||||
// Calculate the desired size and position based on the other application's window
|
||||
var renderRect = GetLargest916Rect(rect);
|
||||
var height = renderRect.Width;
|
||||
var left = rect.Left + ((rect.Right - rect.Left) - renderRect.Width) / 2; // Center horizontally
|
||||
var top = rect.Bottom - height;
|
||||
var height = renderRect.Height;
|
||||
var left = rect.Left + (rect.Right - rect.Left - renderRect.Width) / 2; // Center horizontally
|
||||
var top = renderRect.Top;
|
||||
return new Rect(left, top, renderRect.Width, height);
|
||||
}
|
||||
}
|
||||
|
@ -56,8 +56,8 @@ class TouchPanelPositionManager
|
|||
var originalWidth = original.Width;
|
||||
var originalHeight = original.Height;
|
||||
|
||||
var widthBasedHeight = (originalWidth * 16) / 9;
|
||||
var heightBasedWidth = (originalHeight * 9) / 16;
|
||||
var widthBasedHeight = originalWidth * 16 / 9;
|
||||
var heightBasedWidth = originalHeight * 9 / 16;
|
||||
|
||||
if (widthBasedHeight <= originalHeight)
|
||||
{
|
|
@ -2,7 +2,7 @@
|
|||
using System.IO.Ports;
|
||||
using System.Windows;
|
||||
|
||||
namespace WpfMaiTouchEmulator;
|
||||
namespace WpfMaiTouchEmulator.Managers;
|
||||
|
||||
internal class VirtualComPortManager
|
||||
{
|
||||
|
@ -21,7 +21,7 @@ internal class VirtualComPortManager
|
|||
public async Task<bool> CheckIfPortInstalled(string port, bool expectToExist)
|
||||
{
|
||||
var installed = false;
|
||||
for (var i = 0; i< 3; i++)
|
||||
for (var i = 0; i < 3; i++)
|
||||
{
|
||||
installed = GetInstalledPorts().Any(x => x == port);
|
||||
if (installed && expectToExist)
|
|
@ -12,7 +12,7 @@ namespace WpfMaiTouchEmulator.Properties {
|
|||
|
||||
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.8.0.0")]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.12.0.0")]
|
||||
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
|
||||
|
||||
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
||||
|
@ -94,5 +94,65 @@ namespace WpfMaiTouchEmulator.Properties {
|
|||
this["UserLanguage"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("True")]
|
||||
public bool IsRingButtonEmulationEnabled {
|
||||
get {
|
||||
return ((bool)(this["IsRingButtonEmulationEnabled"]));
|
||||
}
|
||||
set {
|
||||
this["IsRingButtonEmulationEnabled"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("0")]
|
||||
public int BorderSetting {
|
||||
get {
|
||||
return ((int)(this["BorderSetting"]));
|
||||
}
|
||||
set {
|
||||
this["BorderSetting"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("")]
|
||||
public string BorderColour {
|
||||
get {
|
||||
return ((string)(this["BorderColour"]));
|
||||
}
|
||||
set {
|
||||
this["BorderColour"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("True")]
|
||||
public bool UserSettingsUpgradeRequired {
|
||||
get {
|
||||
return ((bool)(this["UserSettingsUpgradeRequired"]));
|
||||
}
|
||||
set {
|
||||
this["UserSettingsUpgradeRequired"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("False")]
|
||||
public bool IsLargeButtonsEnabled {
|
||||
get {
|
||||
return ((bool)(this["IsLargeButtonsEnabled"]));
|
||||
}
|
||||
set {
|
||||
this["IsLargeButtonsEnabled"] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,5 +20,20 @@
|
|||
<Setting Name="UserLanguage" Type="System.String" Scope="User">
|
||||
<Value Profile="(Default)" />
|
||||
</Setting>
|
||||
<Setting Name="IsRingButtonEmulationEnabled" Type="System.Boolean" Scope="User">
|
||||
<Value Profile="(Default)">True</Value>
|
||||
</Setting>
|
||||
<Setting Name="BorderSetting" Type="System.Int32" Scope="User">
|
||||
<Value Profile="(Default)">0</Value>
|
||||
</Setting>
|
||||
<Setting Name="BorderColour" Type="System.String" Scope="User">
|
||||
<Value Profile="(Default)" />
|
||||
</Setting>
|
||||
<Setting Name="UserSettingsUpgradeRequired" Type="System.Boolean" Scope="User">
|
||||
<Value Profile="(Default)">True</Value>
|
||||
</Setting>
|
||||
<Setting Name="IsLargeButtonsEnabled" Type="System.Boolean" Scope="User">
|
||||
<Value Profile="(Default)">False</Value>
|
||||
</Setting>
|
||||
</Settings>
|
||||
</SettingsFile>
|
|
@ -7,11 +7,11 @@
|
|||
# デモ
|
||||
|
||||
|
||||
https://github.com/Leapward-Koex/MaiTouchSensorEmulator/assets/30615050/eea21285-fec5-4393-a75d-74274b39789f
|
||||
https://github.com/user-attachments/assets/fd0d8f08-586b-416e-8e49-7e389a08d02b
|
||||
|
||||
|
||||
|
||||
https://github.com/Leapward-Koex/MaiTouchSensorEmulator/assets/30615050/e45ca02f-8d82-4ad4-a610-ef08abcb5087
|
||||
https://github.com/user-attachments/assets/1862e59b-520c-4cd5-adf4-37389a75815d
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -13,11 +13,11 @@ The app uses com0com to install a virtual COM port pairing of COM3 - COM23. The
|
|||
# Demo
|
||||
|
||||
|
||||
https://github.com/Leapward-Koex/MaiTouchSensorEmulator/assets/30615050/eea21285-fec5-4393-a75d-74274b39789f
|
||||
https://github.com/user-attachments/assets/fd0d8f08-586b-416e-8e49-7e389a08d02b
|
||||
|
||||
|
||||
|
||||
https://github.com/Leapward-Koex/MaiTouchSensorEmulator/assets/30615050/e45ca02f-8d82-4ad4-a610-ef08abcb5087
|
||||
https://github.com/user-attachments/assets/1862e59b-520c-4cd5-adf4-37389a75815d
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -7,11 +7,11 @@
|
|||
# 演示
|
||||
|
||||
|
||||
https://github.com/Leapward-Koex/MaiTouchSensorEmulator/assets/30615050/eea21285-fec5-4393-a75d-74274b39789f
|
||||
https://github.com/user-attachments/assets/fd0d8f08-586b-416e-8e49-7e389a08d02b
|
||||
|
||||
|
||||
|
||||
https://github.com/Leapward-Koex/MaiTouchSensorEmulator/assets/30615050/e45ca02f-8d82-4ad4-a610-ef08abcb5087
|
||||
https://github.com/user-attachments/assets/1862e59b-520c-4cd5-adf4-37389a75815d
|
||||
|
||||
|
||||
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -60,6 +60,15 @@ namespace WpfMaiTouchEmulator.Resources {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to About.
|
||||
/// </summary>
|
||||
internal static string LbAbout {
|
||||
get {
|
||||
return ResourceManager.GetString("LbAbout", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Automatic port connecting.
|
||||
/// </summary>
|
||||
|
@ -96,6 +105,42 @@ namespace WpfMaiTouchEmulator.Resources {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Disabled.
|
||||
/// </summary>
|
||||
internal static string LbBorderDisabled {
|
||||
get {
|
||||
return ResourceManager.GetString("LbBorderDisabled", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Rainbow.
|
||||
/// </summary>
|
||||
internal static string LbBorderRainbow {
|
||||
get {
|
||||
return ResourceManager.GetString("LbBorderRainbow", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Border Settings.
|
||||
/// </summary>
|
||||
internal static string LbBorderSettings {
|
||||
get {
|
||||
return ResourceManager.GetString("LbBorderSettings", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Solid.
|
||||
/// </summary>
|
||||
internal static string LbBorderSolid {
|
||||
get {
|
||||
return ResourceManager.GetString("LbBorderSolid", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Button State.
|
||||
/// </summary>
|
||||
|
@ -105,6 +150,15 @@ namespace WpfMaiTouchEmulator.Resources {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to COM Port.
|
||||
/// </summary>
|
||||
internal static string LbComPort {
|
||||
get {
|
||||
return ResourceManager.GetString("LbComPort", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Connection state.
|
||||
/// </summary>
|
||||
|
@ -141,6 +195,33 @@ namespace WpfMaiTouchEmulator.Resources {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Show the touchpad with translucency and show inputs highlighted.
|
||||
/// </summary>
|
||||
internal static string lbDebugModeTT {
|
||||
get {
|
||||
return ResourceManager.GetString("lbDebugModeTT", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Emulate ring buttons.
|
||||
/// </summary>
|
||||
internal static string lbEmulateRingButtons {
|
||||
get {
|
||||
return ResourceManager.GetString("lbEmulateRingButtons", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Useful when navigating the menus without a keyboard.
|
||||
/// </summary>
|
||||
internal static string lbEmulateRingButtonsTT {
|
||||
get {
|
||||
return ResourceManager.GetString("lbEmulateRingButtonsTT", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Exit when Sinmai exits.
|
||||
/// </summary>
|
||||
|
@ -177,6 +258,24 @@ namespace WpfMaiTouchEmulator.Resources {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Extend ring button size.
|
||||
/// </summary>
|
||||
internal static string lbLargeButtons {
|
||||
get {
|
||||
return ResourceManager.GetString("lbLargeButtons", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Extends the ring button hitboxes to the edge of the window.
|
||||
/// </summary>
|
||||
internal static string lbLargeButtonsTT {
|
||||
get {
|
||||
return ResourceManager.GetString("lbLargeButtonsTT", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to List installed com ports.
|
||||
/// </summary>
|
||||
|
@ -205,7 +304,16 @@ namespace WpfMaiTouchEmulator.Resources {
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Recieved.
|
||||
/// Looks up a localized string similar to Open log folder.
|
||||
/// </summary>
|
||||
internal static string LbOpenLogFolder {
|
||||
get {
|
||||
return ResourceManager.GetString("LbOpenLogFolder", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Received.
|
||||
/// </summary>
|
||||
internal static string lbRecievedData {
|
||||
get {
|
||||
|
@ -222,6 +330,15 @@ namespace WpfMaiTouchEmulator.Resources {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Settings.
|
||||
/// </summary>
|
||||
internal static string LbSettings {
|
||||
get {
|
||||
return ResourceManager.GetString("LbSettings", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Drag.
|
||||
/// </summary>
|
||||
|
|
|
@ -117,6 +117,9 @@
|
|||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="LbAbout" xml:space="preserve">
|
||||
<value>について</value>
|
||||
</data>
|
||||
<data name="lbAutoPortConnecting" xml:space="preserve">
|
||||
<value>自動ポート接続</value>
|
||||
</data>
|
||||
|
@ -129,9 +132,24 @@
|
|||
<data name="lbAutoSensorPositioningTT" xml:space="preserve">
|
||||
<value>Sinmai.exeの上に正しい位置にタッチセンサーウィンドウを自動的に移動しようとする</value>
|
||||
</data>
|
||||
<data name="LbBorderDisabled" xml:space="preserve">
|
||||
<value>無効</value>
|
||||
</data>
|
||||
<data name="LbBorderRainbow" xml:space="preserve">
|
||||
<value>レインボー</value>
|
||||
</data>
|
||||
<data name="LbBorderSettings" xml:space="preserve">
|
||||
<value>境界線設定</value>
|
||||
</data>
|
||||
<data name="LbBorderSolid" xml:space="preserve">
|
||||
<value>単色</value>
|
||||
</data>
|
||||
<data name="lbButtonState" xml:space="preserve">
|
||||
<value>ボタン状態</value>
|
||||
</data>
|
||||
<data name="LbComPort" xml:space="preserve">
|
||||
<value>COMポート</value>
|
||||
</data>
|
||||
<data name="lbConnectionState" xml:space="preserve">
|
||||
<value>接続状態</value>
|
||||
</data>
|
||||
|
@ -144,6 +162,15 @@
|
|||
<data name="lbDebugMode" xml:space="preserve">
|
||||
<value>デバッグモード</value>
|
||||
</data>
|
||||
<data name="lbDebugModeTT" xml:space="preserve">
|
||||
<value>タッチパッドを半透明で表示し、入力をハイライト表示</value>
|
||||
</data>
|
||||
<data name="lbEmulateRingButtons" xml:space="preserve">
|
||||
<value>リングボタンをエミュレートする</value>
|
||||
</data>
|
||||
<data name="lbEmulateRingButtonsTT" xml:space="preserve">
|
||||
<value>キーボードがないときにメニュー操作に便利</value>
|
||||
</data>
|
||||
<data name="lbExitWithSinmai" xml:space="preserve">
|
||||
<value>Sinmai終了時に終了</value>
|
||||
</data>
|
||||
|
@ -156,6 +183,12 @@
|
|||
<data name="lbLanguageDropdown" xml:space="preserve">
|
||||
<value>言語</value>
|
||||
</data>
|
||||
<data name="lbLargeButtons" xml:space="preserve">
|
||||
<value>リングボタンのサイズを拡大</value>
|
||||
</data>
|
||||
<data name="lbLargeButtonsTT" xml:space="preserve">
|
||||
<value>リングボタンのヒットボックスをウィンドウの端まで拡大</value>
|
||||
</data>
|
||||
<data name="lbListComPorts" xml:space="preserve">
|
||||
<value>インストールされたCOMポートをリストアップ</value>
|
||||
</data>
|
||||
|
@ -165,12 +198,18 @@
|
|||
<data name="lbMenuItemSetup" xml:space="preserve">
|
||||
<value>セットアップ指示を表示</value>
|
||||
</data>
|
||||
<data name="LbOpenLogFolder" xml:space="preserve">
|
||||
<value>ログフォルダを開く</value>
|
||||
</data>
|
||||
<data name="lbRecievedData" xml:space="preserve">
|
||||
<value>受信データ</value>
|
||||
</data>
|
||||
<data name="lbSentData" xml:space="preserve">
|
||||
<value>送信データ</value>
|
||||
</data>
|
||||
<data name="LbSettings" xml:space="preserve">
|
||||
<value>設定</value>
|
||||
</data>
|
||||
<data name="LbTouchPanelDrag" xml:space="preserve">
|
||||
<value>ドラッグ</value>
|
||||
</data>
|
||||
|
|
|
@ -117,6 +117,9 @@
|
|||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="LbAbout" xml:space="preserve">
|
||||
<value>About</value>
|
||||
</data>
|
||||
<data name="lbAutoPortConnecting" xml:space="preserve">
|
||||
<value>Automatic port connecting</value>
|
||||
</data>
|
||||
|
@ -129,9 +132,24 @@
|
|||
<data name="lbAutoSensorPositioningTT" xml:space="preserve">
|
||||
<value>Try and automatically move the touch sensor window into the correct position on top of Sinmai.exe</value>
|
||||
</data>
|
||||
<data name="LbBorderDisabled" xml:space="preserve">
|
||||
<value>Disabled</value>
|
||||
</data>
|
||||
<data name="LbBorderRainbow" xml:space="preserve">
|
||||
<value>Rainbow</value>
|
||||
</data>
|
||||
<data name="LbBorderSettings" xml:space="preserve">
|
||||
<value>Border Settings</value>
|
||||
</data>
|
||||
<data name="LbBorderSolid" xml:space="preserve">
|
||||
<value>Solid</value>
|
||||
</data>
|
||||
<data name="lbButtonState" xml:space="preserve">
|
||||
<value>Button State</value>
|
||||
</data>
|
||||
<data name="LbComPort" xml:space="preserve">
|
||||
<value>COM Port</value>
|
||||
</data>
|
||||
<data name="lbConnectionState" xml:space="preserve">
|
||||
<value>Connection state</value>
|
||||
</data>
|
||||
|
@ -144,6 +162,15 @@
|
|||
<data name="lbDebugMode" xml:space="preserve">
|
||||
<value>Debug mode</value>
|
||||
</data>
|
||||
<data name="lbDebugModeTT" xml:space="preserve">
|
||||
<value>Show the touchpad with translucency and show inputs highlighted</value>
|
||||
</data>
|
||||
<data name="lbEmulateRingButtons" xml:space="preserve">
|
||||
<value>Emulate ring buttons</value>
|
||||
</data>
|
||||
<data name="lbEmulateRingButtonsTT" xml:space="preserve">
|
||||
<value>Useful when navigating the menus without a keyboard</value>
|
||||
</data>
|
||||
<data name="lbExitWithSinmai" xml:space="preserve">
|
||||
<value>Exit when Sinmai exits</value>
|
||||
</data>
|
||||
|
@ -156,6 +183,12 @@
|
|||
<data name="lbLanguageDropdown" xml:space="preserve">
|
||||
<value>Language</value>
|
||||
</data>
|
||||
<data name="lbLargeButtons" xml:space="preserve">
|
||||
<value>Extend ring button size</value>
|
||||
</data>
|
||||
<data name="lbLargeButtonsTT" xml:space="preserve">
|
||||
<value>Extends the ring button hitboxes to the edge of the window</value>
|
||||
</data>
|
||||
<data name="lbListComPorts" xml:space="preserve">
|
||||
<value>List installed com ports</value>
|
||||
</data>
|
||||
|
@ -165,12 +198,18 @@
|
|||
<data name="lbMenuItemSetup" xml:space="preserve">
|
||||
<value>Show setup instructions</value>
|
||||
</data>
|
||||
<data name="LbOpenLogFolder" xml:space="preserve">
|
||||
<value>Open log folder</value>
|
||||
</data>
|
||||
<data name="lbRecievedData" xml:space="preserve">
|
||||
<value>Recieved</value>
|
||||
<value>Received</value>
|
||||
</data>
|
||||
<data name="lbSentData" xml:space="preserve">
|
||||
<value>Sent</value>
|
||||
</data>
|
||||
<data name="LbSettings" xml:space="preserve">
|
||||
<value>Settings</value>
|
||||
</data>
|
||||
<data name="LbTouchPanelDrag" xml:space="preserve">
|
||||
<value>Drag</value>
|
||||
</data>
|
||||
|
|
|
@ -117,6 +117,9 @@
|
|||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="LbAbout" xml:space="preserve">
|
||||
<value>关于</value>
|
||||
</data>
|
||||
<data name="lbAutoPortConnecting" xml:space="preserve">
|
||||
<value>自动连接端口</value>
|
||||
</data>
|
||||
|
@ -129,9 +132,24 @@
|
|||
<data name="lbAutoSensorPositioningTT" xml:space="preserve">
|
||||
<value>尝试自动移动触摸传感器窗口到Sinmai.exe上方的正确位置</value>
|
||||
</data>
|
||||
<data name="LbBorderDisabled" xml:space="preserve">
|
||||
<value>無効</value>
|
||||
</data>
|
||||
<data name="LbBorderRainbow" xml:space="preserve">
|
||||
<value>彩虹</value>
|
||||
</data>
|
||||
<data name="LbBorderSettings" xml:space="preserve">
|
||||
<value>境界線設定</value>
|
||||
</data>
|
||||
<data name="LbBorderSolid" xml:space="preserve">
|
||||
<value>纯色</value>
|
||||
</data>
|
||||
<data name="lbButtonState" xml:space="preserve">
|
||||
<value>按钮状态</value>
|
||||
</data>
|
||||
<data name="LbComPort" xml:space="preserve">
|
||||
<value>COM端口</value>
|
||||
</data>
|
||||
<data name="lbConnectionState" xml:space="preserve">
|
||||
<value>连接状态</value>
|
||||
</data>
|
||||
|
@ -144,6 +162,15 @@
|
|||
<data name="lbDebugMode" xml:space="preserve">
|
||||
<value>调试模式</value>
|
||||
</data>
|
||||
<data name="lbDebugModeTT" xml:space="preserve">
|
||||
<value>显示半透明的触控板并突出显示输入</value>
|
||||
</data>
|
||||
<data name="lbEmulateRingButtons" xml:space="preserve">
|
||||
<value>模拟环形按钮</value>
|
||||
</data>
|
||||
<data name="lbEmulateRingButtonsTT" xml:space="preserve">
|
||||
<value>在没有键盘的情况下导航菜单时很有用</value>
|
||||
</data>
|
||||
<data name="lbExitWithSinmai" xml:space="preserve">
|
||||
<value>随Sinmai退出</value>
|
||||
</data>
|
||||
|
@ -156,6 +183,12 @@
|
|||
<data name="lbLanguageDropdown" xml:space="preserve">
|
||||
<value>语言</value>
|
||||
</data>
|
||||
<data name="lbLargeButtons" xml:space="preserve">
|
||||
<value>扩大环形按钮大小</value>
|
||||
</data>
|
||||
<data name="lbLargeButtonsTT" xml:space="preserve">
|
||||
<value>将环形按钮的碰撞盒扩展到窗口边缘</value>
|
||||
</data>
|
||||
<data name="lbListComPorts" xml:space="preserve">
|
||||
<value>列出已安装的COM端口</value>
|
||||
</data>
|
||||
|
@ -165,12 +198,18 @@
|
|||
<data name="lbMenuItemSetup" xml:space="preserve">
|
||||
<value>显示设置说明</value>
|
||||
</data>
|
||||
<data name="LbOpenLogFolder" xml:space="preserve">
|
||||
<value>打开日志文件夹</value>
|
||||
</data>
|
||||
<data name="lbRecievedData" xml:space="preserve">
|
||||
<value>已接收数据</value>
|
||||
</data>
|
||||
<data name="lbSentData" xml:space="preserve">
|
||||
<value>已发送数据</value>
|
||||
</data>
|
||||
<data name="LbSettings" xml:space="preserve">
|
||||
<value>设置</value>
|
||||
</data>
|
||||
<data name="LbTouchPanelDrag" xml:space="preserve">
|
||||
<value>拖动</value>
|
||||
</data>
|
||||
|
|
166
TouchPanel.xaml
166
TouchPanel.xaml
|
@ -3,69 +3,121 @@
|
|||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:local="clr-namespace:WpfMaiTouchEmulator"
|
||||
xmlns:local="clr-namespace:WpfMaiTouchEmulator.Managers"
|
||||
mc:Ignorable="d"
|
||||
Title="TouchPanel" Height="800" Width="800"
|
||||
Title="TouchPanel" Height="1280" Width="720"
|
||||
ResizeMode="NoResize"
|
||||
AllowsTransparency="True" WindowStyle="None" Background="Transparent"
|
||||
>
|
||||
<Window.Resources>
|
||||
<Style x:Key="DraggableHandleStyle" TargetType="Border">
|
||||
<Setter Property="Background">
|
||||
<Setter.Value>
|
||||
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
|
||||
<GradientStop Color="#FFEEEEEE" Offset="0"/>
|
||||
<GradientStop Color="#FFCCCCCC" Offset="1"/>
|
||||
</LinearGradientBrush>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
<Setter Property="CornerRadius" Value="10"/>
|
||||
<Setter Property="Effect">
|
||||
<Setter.Value>
|
||||
<DropShadowEffect Color="Black" BlurRadius="5" ShadowDepth="2"/>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
<Style x:Key="ResizeGripStyle" TargetType="Border">
|
||||
<Setter Property="Background">
|
||||
<Setter.Value>
|
||||
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
|
||||
<GradientStop Color="#FFCCCCCC" Offset="0"/>
|
||||
<GradientStop Color="#FFAAAAAA" Offset="1"/>
|
||||
</LinearGradientBrush>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
<Setter Property="CornerRadius" Value="10"/>
|
||||
<Setter Property="Effect">
|
||||
<Setter.Value>
|
||||
<DropShadowEffect Color="Black" BlurRadius="5" ShadowDepth="2"/>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
</Window.Resources>
|
||||
<Border Background="#01000000">
|
||||
<StackPanel>
|
||||
<Viewbox Stretch="Uniform" Opacity="1">
|
||||
<Canvas x:Name="TouchCanvas" Width="1440" Height="1440">
|
||||
<Border x:Name="DragWindowHandle" HorizontalAlignment="Center" VerticalAlignment="Top"
|
||||
Height="95" Background="White" MouseLeftButtonDown="DragBar_MouseLeftButtonDown"
|
||||
Cursor="SizeAll" Width="130">
|
||||
<Label FontSize="50" Content="{Binding LbTouchPanelDrag}" d:Content="Drag" />
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Border x:Name="DragWindowHandle"
|
||||
HorizontalAlignment="Left" VerticalAlignment="Top"
|
||||
Height="50" Width="100"
|
||||
Style="{StaticResource DraggableHandleStyle}"
|
||||
MouseLeftButtonDown="DragBar_MouseLeftButtonDown"
|
||||
Cursor="SizeAll">
|
||||
<TextBlock FontSize="24" Text="{Binding LbTouchPanelDrag}"
|
||||
VerticalAlignment="Center" HorizontalAlignment="Center" d:Text="Drag"/>
|
||||
</Border>
|
||||
<DockPanel VerticalAlignment="Bottom">
|
||||
<Viewbox Stretch="Uniform" Opacity="1">
|
||||
<Border x:Name="touchPanelBorder" BorderThickness="10"
|
||||
CornerRadius="720"
|
||||
Width="1440" VerticalAlignment="Bottom">
|
||||
<Canvas x:Name="TouchCanvas" Width="1440" Height="1440" Margin="-10,-10,-10,-10">
|
||||
|
||||
<Polygon Canvas.Left="620" Canvas.Top="6" Points="0,5 50,2 100,0 150,2 200,5 165,253 100,188 35,253" Tag="{x:Static local:TouchValue.D1}" Fill="White" />
|
||||
<Polygon Canvas.Left="786" Canvas.Top="11" Points="150,28 245,65 360,133 208,338 145,338 49,297 0,249 35,0" Tag="{x:Static local:TouchValue.A1}" Fill="White" />
|
||||
<Polygon Canvas.Left="995" Canvas.Top="144" Points="153,0 187,32 225,67 259,104 295,147 96,297 96,205 0,205" Tag="{x:Static local:TouchValue.D2}" Fill="White" />
|
||||
<Polygon Canvas.Left="1091" Canvas.Top="292" Points="261,101 303,195 339,327 91,362 42,314 0,219 0,150 202,0" Tag="{x:Static local:TouchValue.A2}" Fill="White" />
|
||||
<Polygon Canvas.Left="1182" Canvas.Top="620" Points="248,0 251,48 253,100 251,150 247,199 0,165 65,100 0,35" Tag="{x:Static local:TouchValue.D3}" Fill="White" />
|
||||
<Polygon Canvas.Left="1092" Canvas.Top="786" Points="305,150 269,246 201,364 0,213 0,144 41,48 89,0 337,34" Tag="{x:Static local:TouchValue.A3}" Fill="White" />
|
||||
<Polygon Canvas.Left="1000" Canvas.Top="1000" Points="292,151 260,187 225,225 188,259 151,291 0,92 92,92 92,0" Tag="{x:Static local:TouchValue.D4}" Fill="White" />
|
||||
<Polygon Canvas.Left="786" Canvas.Top="1092" Points="260,259 167,301 37,335 0,83 48,35 144,0 212,0 364,200" Tag="{x:Static local:TouchValue.A4}" Fill="White" />
|
||||
<Polygon Canvas.Left="621" Canvas.Top="1175" Points="199,252 151,255 99,257 49,255 0,252 34,0 99,65 164,0" Tag="{x:Static local:TouchValue.D5}" Fill="White" />
|
||||
<Polygon Canvas.Left="291" Canvas.Top="1092" Points="104,259 197,301 327,335 363,83 316,35 220,0 152,0 0,201" Tag="{x:Static local:TouchValue.A5}" Fill="White" />
|
||||
<Polygon Canvas.Left="150" Canvas.Top="1000" Points="140,292 104,260 66,225 32,188 0,151 199,0 199,92 291,92" Tag="{x:Static local:TouchValue.D6}" Fill="White" />
|
||||
<Polygon Canvas.Left="16" Canvas.Top="785" Points="32,150 68,246 133,365 333,214 333,144 296,48 248,0 0,35" Tag="{x:Static local:TouchValue.A6}" Fill="White" />
|
||||
<Polygon Canvas.Left="10" Canvas.Top="620" Points="5,199 2,151 0,99 2,49 6,0 253,34 188,99 253,164" Tag="{x:Static local:TouchValue.D7}" Fill="White" />
|
||||
<Polygon Canvas.Left="16" Canvas.Top="291" Points="78,101 36,195 0,327 248,362 297,314 333,219 333,151 132,0" Tag="{x:Static local:TouchValue.A7}" Fill="White" />
|
||||
<Polygon Canvas.Left="149" Canvas.Top="150" Points="0,140 32,104 67,66 104,32 145,0 298,199 200,199 200,291" Tag="{x:Static local:TouchValue.D8}" Fill="White" />
|
||||
<Polygon Canvas.Left="295" Canvas.Top="11" Points="210,28 115,65 0,138 153,338 215,338 311,297 359,249 324,0" Tag="{x:Static local:TouchValue.A8}" Fill="White" />
|
||||
|
||||
<Polygon Canvas.Left="607" Canvas.Top="195" Points="0,113 113,0 226,113 113,226" Tag="{x:Static local:TouchValue.E1}" Fill="White" />
|
||||
<Polygon Canvas.Left="720" Canvas.Top="346" Points="0,78 78,0 209,55 209,165 180,195 70,195 0,130" Tag="{x:Static local:TouchValue.B1}" Fill="White" />
|
||||
<Polygon Canvas.Left="930" Canvas.Top="350" Points="0,0 0,160 160,160, 160,0 0,0" Tag="{x:Static local:TouchValue.E2}" Fill="White" />
|
||||
<Polygon Canvas.Left="900" Canvas.Top="511" Points="117,209 195,132 140,0 30,0 0,30 0,139 65,209" Tag="{x:Static local:TouchValue.B2}" Fill="White" />
|
||||
<Polygon Canvas.Left="1020" Canvas.Top="607" Points="0,113 113,0 226,113 113,226" Tag="{x:Static local:TouchValue.E3}" Fill="White" />
|
||||
<Polygon Canvas.Left="900" Canvas.Top="721" Points="120,0 198,78 140,208 30,208 0,180 0,71 65,0" Tag="{x:Static local:TouchValue.B3}" Fill="White" />
|
||||
<Polygon Canvas.Left="930" Canvas.Top="930" Points="0,0 0,160 160,160, 160,0 0,0" Tag="{x:Static local:TouchValue.E4}" Fill="White" />
|
||||
<Polygon Canvas.Left="721" Canvas.Top="901" Points="0,112 87,198 208,140 208,29 177,0 71,0 0,65" Tag="{x:Static local:TouchValue.B4}" Fill="White" />
|
||||
<Polygon Canvas.Left="607" Canvas.Top="1013" Points="0,113 113,0 226,113 113,226" Tag="{x:Static local:TouchValue.E5}" Fill="White" />
|
||||
<Polygon Canvas.Left="512" Canvas.Top="901" Points="208,112 121,198 0,140 0,29 31,0 137,0 208,65" Tag="{x:Static local:TouchValue.B5}" Fill="White" />
|
||||
<Polygon Canvas.Left="350" Canvas.Top="930" Points="0,0 0,160 160,160, 160,0 0,0" Tag="{x:Static local:TouchValue.E6}" Fill="White" />
|
||||
<Polygon Canvas.Left="349" Canvas.Top="721" Points="78,0 0,78 58,208 163,208 193,180 193,71 133,0" Tag="{x:Static local:TouchValue.B6}" Fill="White" />
|
||||
<Polygon Canvas.Left="200" Canvas.Top="607" Points="0,113 113,0 226,113 113,226" Tag="{x:Static local:TouchValue.E7}" Fill="White" />
|
||||
<Polygon Canvas.Left="345" Canvas.Top="511" Points="82,209 0,127 55,0 165,0 195,30 195,139 137,209" Tag="{x:Static local:TouchValue.B7}" Fill="White" />
|
||||
<Polygon Canvas.Left="350" Canvas.Top="350" Points="0,0 0,160 160,160, 160,0 0,0" Tag="{x:Static local:TouchValue.E8}" Fill="White" />
|
||||
<Polygon Canvas.Left="511" Canvas.Top="346" Points="209,78 131,0 0,55 0,165 29,195 139,195 209,130" Tag="{x:Static local:TouchValue.B8}" Fill="White" />
|
||||
|
||||
<Polygon Canvas.Left="720" Canvas.Top="583" Points="0,0 60,0 140,80 140,200 60,280 0,280 0,0" Tag="{x:Static local:TouchValue.C1}" Fill="White" />
|
||||
<Polygon Canvas.Left="579" Canvas.Top="583" Points="141,280 81,280 0,199 1,81 81,0 141,0 141,280" Tag="{x:Static local:TouchValue.C2}" Fill="White" />
|
||||
|
||||
|
||||
<Border x:Name="ResizeGrip" Width="150" Height="90"
|
||||
Style="{StaticResource ResizeGripStyle}"
|
||||
MouseDown="ResizeGrip_MouseDown"
|
||||
Canvas.Left="1290" Canvas.Top="1350"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Top">
|
||||
<TextBlock FontSize="50" Text="{Binding LbTouchPanelResize}"
|
||||
VerticalAlignment="Center" HorizontalAlignment="Center" d:Text="Resize"/>
|
||||
</Border>
|
||||
|
||||
</Canvas>
|
||||
</Border>
|
||||
<Polygon Canvas.Left="699" Canvas.Top="6" Points="0,0 39,0 111,5 113,6 111,24 80,243 77,243 63,229 56,221 23,188 16,194 -34,244 -36,244 -70,4 -70,3 0,0" PreviewTouchDown="Element_TouchDown" PreviewTouchMove="Element_TouchMove" PreviewTouchUp="Element_TouchUp" Tag="{x:Static local:TouchValue.D1}" Fill="White" />
|
||||
<Polygon Canvas.Left="825" Canvas.Top="13" Points="0,0 10,1 95,19 145,37 179,50 207,64 230,75 254,87 297,116 318,130 316,135 300,156 286,175 270,196 256,215 240,236 226,255 210,276 197,294 181,315 168,333 101,333 66,318 21,299 9,293 -35,249 -34,237 -1,4 0,0" PreviewTouchDown="Element_TouchDown" PreviewTouchMove="Element_TouchMove" PreviewTouchUp="Element_TouchUp" Tag="{x:Static local:TouchValue.A1}" Fill="White" />
|
||||
<Polygon Canvas.Left="1156" Canvas.Top="154" Points="0,0 8,6 21,18 32,27 45,39 56,48 69,60 77,67 86,77 93,85 105,99 116,111 125,122 130,128 118,138 102,150 85,163 68,176 47,192 30,205 13,218 -8,234 -25,247 -42,260 -62,275 -63,275 -63,255 -62,207 -61,193 -143,193 -141,189 -127,170 -111,149 -97,130 -81,109 -68,91 -52,70 -38,51 -22,30 -8,11 0,0" PreviewTouchDown="Element_TouchDown" PreviewTouchMove="Element_TouchMove" PreviewTouchUp="Element_TouchUp" Tag="{x:Static local:TouchValue.D2}" Fill="White" />
|
||||
<Polygon Canvas.Left="1295" Canvas.Top="294" Points="0,0 4,5 21,31 34,51 44,69 89,159 106,213 123,268 132,318 132,320 -116,354 -120,352 -164,308 -179,271 -195,232 -201,217 -201,151 -190,142 -171,128 -150,112 -131,98 -110,82 -91,68 -70,52 -51,38 -30,22 -11,8 0,0" PreviewTouchDown="Element_TouchDown" PreviewTouchMove="Element_TouchMove" PreviewTouchUp="Element_TouchUp" Tag="{x:Static local:TouchValue.A2}" Fill="White" />
|
||||
<Polygon Canvas.Left="1427" Canvas.Top="628" Points="0,0 3,0 5,30 8,90 7,116 4,174 3,183 -15,181 -235,150 -235,147 -216,128 -208,121 -182,95 -179,92 -187,85 -237,35 -237,34 -13,2 0,0" PreviewTouchDown="Element_TouchDown" PreviewTouchMove="Element_TouchMove" PreviewTouchUp="Element_TouchUp" Tag="{x:Static local:TouchValue.D3}" Fill="White" />
|
||||
<Polygon Canvas.Left="1176" Canvas.Top="791" Points="0,0 13,1 247,33 251,34 250,43 238,100 223,144 208,187 195,224 182,248 169,271 159,290 146,313 136,329 121,351 119,352 101,339 80,323 61,309 40,293 21,279 0,263 -19,249 -40,233 -59,219 -80,203 -82,202 -82,136 -67,99 -45,44 -38,37 -30,30" PreviewTouchDown="Element_TouchDown" PreviewTouchMove="Element_TouchMove" PreviewTouchUp="Element_TouchUp" Tag="{x:Static local:TouchValue.A3}" Fill="White" />
|
||||
<Polygon Canvas.Left="1094" Canvas.Top="1010" Points="0,0 4,2 20,14 33,24 54,40 75,56 95,71 113,85 129,97 146,110 167,126 188,142 193,146 191,150 179,163 168,175 159,185 147,198 136,210 132,215 124,222 111,234 99,245 87,256 77,265 67,274 63,272 51,256 41,243 28,226 18,213 5,196 -8,179 -18,166 -31,149 -41,136 -54,119 -67,102 -77,89 -81,83 1,83" PreviewTouchDown="Element_TouchDown" PreviewTouchMove="Element_TouchMove" PreviewTouchUp="Element_TouchUp" Tag="{x:Static local:TouchValue.D4}" Fill="White" />
|
||||
<Polygon Canvas.Left="927" Canvas.Top="1093" Points="0,0 67,0 81,18 95,37 111,58 126,78 142,99 154,115 170,136 184,155 194,168 210,189 219,201 214,205 189,221 172,232 150,246 136,254 108,268 85,279 72,285 10,307 -7,313 -98,333 -101,333 -103,324 -135,88 -135,82 -128,75 -121,67 -92,38 -56,23 -15,6" PreviewTouchDown="Element_TouchDown" PreviewTouchMove="Element_TouchMove" PreviewTouchUp="Element_TouchUp" Tag="{x:Static local:TouchValue.A4}" Fill="White" />
|
||||
<Polygon Canvas.Left="664" Canvas.Top="1190" Points="0,0 7,6 18,17 26,24 44,42 52,49 58,54 90,22 98,15 113,0 115,1 148,234 148,238 146,239 66,244 54,244 -35,238 -10,63 -1,1" PreviewTouchDown="Element_TouchDown" PreviewTouchMove="Element_TouchMove" PreviewTouchUp="Element_TouchUp" Tag="{x:Static local:TouchValue.D5}" Fill="White" />
|
||||
<Polygon Canvas.Left="448" Canvas.Top="1092" Points="0,0 66,0 112,19 156,37 164,44 202,82 197,121 168,331 167,334 153,332 106,323 1,288 -97,239 -135,214 -152,203 -151,199 -135,178 -120,158 -104,137 -88,116 -79,104 -63,83 -51,67 -35,46 -23,30 -7,9 0,0" PreviewTouchDown="Element_TouchDown" PreviewTouchMove="Element_TouchMove" PreviewTouchUp="Element_TouchUp" Tag="{x:Static local:TouchValue.A5}" Fill="White" />
|
||||
<Polygon Canvas.Left="347" Canvas.Top="1013" Points="0,0 2,0 2,74 1,80 46,79 84,79 82,83 69,100 56,117 43,134 30,151 17,168 4,185 -9,202 -22,219 -35,236 -48,253 -61,270 -64,270 -77,258 -85,251 -99,239 -111,228 -122,219 -135,207 -144,196 -156,183 -165,172 -177,159 -186,148 -191,142 -172,128 -153,114 -132,98 -118,88 -97,72 -79,59 -58,43 -39,29 -20,15 0,0" PreviewTouchDown="Element_TouchDown" PreviewTouchMove="Element_TouchMove" PreviewTouchUp="Element_TouchUp" Tag="{x:Static local:TouchValue.D6}" Fill="White" />
|
||||
<Polygon Canvas.Left="257" Canvas.Top="791" Points="0,0 9,0 52,43 65,73 83,116 91,135 91,202 73,216 54,230 36,244 17,258 -1,272 -20,286 -33,296 -54,312 -73,326 -91,340 -109,353 -111,353 -123,334 -135,316 -148,296 -182,228 -192,209 -201,190 -228,103 -233,85 -241,39 -241,34 -240,33 0,0" PreviewTouchDown="Element_TouchDown" PreviewTouchMove="Element_TouchMove" PreviewTouchUp="Element_TouchUp" Tag="{x:Static local:TouchValue.A6}" Fill="White" />
|
||||
<Polygon Canvas.Left="13" Canvas.Top="627" Points="0,0 24,3 238,33 232,40 223,50 203,70 196,78 183,91 185,95 240,150 240,151 139,165 7,183 0,183 -7,89 -1,1 0,0" PreviewTouchDown="Element_TouchDown" PreviewTouchMove="Element_TouchMove" PreviewTouchUp="Element_TouchUp" Tag="{x:Static local:TouchValue.D7}" Fill="White" />
|
||||
<Polygon Canvas.Left="145" Canvas.Top="295" Points="0,0 5,2 26,18 42,30 63,46 82,60 103,76 122,90 140,104 159,118 180,134 199,148 203,151 203,193 202,220 180,274 165,311 154,322 146,329 122,353 108,352 -130,320 -131,318 -123,274 -96,187 -87,157 -66,115 -55,92 -44,70 -30,48 -14,22 -2,3 0,0" PreviewTouchDown="Element_TouchDown" PreviewTouchMove="Element_TouchMove" PreviewTouchUp="Element_TouchUp" Tag="{x:Static local:TouchValue.A7}" Fill="White" />
|
||||
<Polygon Canvas.Left="283" Canvas.Top="155" Points="0,0 5,5 17,20 29,36 42,53 58,74 74,95 90,116 106,137 119,154 135,175 146,190 146,191 65,191 66,256 66,275 58,269 46,260 29,247 12,234 -5,221 -22,208 -39,195 -56,182 -73,169 -90,156 -107,143 -124,130 -128,126 -119,117 -112,109 -101,97 -94,89 -82,76 -75,68 -64,56 -52,45 -41,36 -29,25 -18,16 -5,4 0,0" PreviewTouchDown="Element_TouchDown" PreviewTouchMove="Element_TouchMove" PreviewTouchUp="Element_TouchUp" Tag="{x:Static local:TouchValue.D8}" Fill="White" />
|
||||
<Polygon Canvas.Left="613" Canvas.Top="13" Points="0,0 3,0 10,48 38,247 37,252 24,265 16,272 -8,296 -100,333 -165,333 -179,315 -192,298 -205,281 -218,264 -231,247 -244,230 -257,213 -270,196 -283,179 -296,162 -309,145 -317,134 -316,131 -300,121 -285,111 -265,98 -249,88 -165,46 -72,15 -9,2 0,0" PreviewTouchDown="Element_TouchDown" PreviewTouchMove="Element_TouchMove" PreviewTouchUp="Element_TouchUp" Tag="{x:Static local:TouchValue.A8}" Fill="White" />
|
||||
</Viewbox>
|
||||
</DockPanel>
|
||||
|
||||
<Polygon Canvas.Left="720" Canvas.Top="215" Points="0,0 4,2 48,46 56,53 97,94 91,101 2,190 -2,188 -10,181 -54,137 -62,130 -96,96 -94,92 -73,71 -65,64 -27,26 -19,19 0,0" PreviewTouchDown="Element_TouchDown" PreviewTouchMove="Element_TouchMove" PreviewTouchUp="Element_TouchUp" Tag="{x:Static local:TouchValue.E1}" Fill="White" />
|
||||
<Polygon Canvas.Left="801" Canvas.Top="347" Points="0,0 25,10 61,25 107,44 129,53 130,54 129,88 126,158 112,171 104,178 91,190 88,192 59,192 -7,191 -12,188 -23,177 -30,169 -38,161 -45,153 -53,145 -60,137 -69,128 -73,123 -73,105 -72,71 -33,32 -25,25 0,0" PreviewTouchDown="Element_TouchDown" PreviewTouchMove="Element_TouchMove" PreviewTouchUp="Element_TouchUp" Tag="{x:Static local:TouchValue.B1}" Fill="White" />
|
||||
<Polygon Canvas.Left="1070" Canvas.Top="361" Points="0,0 8,0 8,137 -127,137 -128,57 -128,1 0,0" PreviewTouchDown="Element_TouchDown" PreviewTouchMove="Element_TouchMove" PreviewTouchUp="Element_TouchUp" Tag="{x:Static local:TouchValue.E2}" Fill="White" />
|
||||
<Polygon Canvas.Left="938" Canvas.Top="513" Points="0,0 103,0 113,23 130,64 150,112 156,126 154,130 141,142 112,171 104,178 83,199 31,199 -19,149 -26,141 -36,131 -37,57 -37,35 -30,28 -22,21 -11,10 -3,3 0,0" PreviewTouchDown="Element_TouchDown" PreviewTouchMove="Element_TouchMove" PreviewTouchUp="Element_TouchUp" Tag="{x:Static local:TouchValue.B2}" Fill="White" />
|
||||
<Polygon Canvas.Left="1130" Canvas.Top="623" Points="0,0 4,2 45,43 53,50 97,94 91,101 2,190 -2,188 -10,181 -55,136 -63,129 -96,96 -94,92 -74,72 -66,65 -28,27 -20,20 0,0" PreviewTouchDown="Element_TouchDown" PreviewTouchMove="Element_TouchMove" PreviewTouchUp="Element_TouchUp" Tag="{x:Static local:TouchValue.E3}" Fill="White" />
|
||||
<Polygon Canvas.Left="968" Canvas.Top="726" Points="0,0 20,0 53,1 109,57 117,64 126,73 123,82 105,125 87,168 74,199 73,200 -31,200 -67,164 -67,123 -66,68 -51,53 -44,45 -5,6 0,0" PreviewTouchDown="Element_TouchDown" PreviewTouchMove="Element_TouchMove" PreviewTouchUp="Element_TouchUp" Tag="{x:Static local:TouchValue.B3}" Fill="White" />
|
||||
<Polygon Canvas.Left="1053" Canvas.Top="939" Points="0,0 25,0 25,137 -110,137 -111,57 -111,1 0,0" PreviewTouchDown="Element_TouchDown" PreviewTouchMove="Element_TouchMove" PreviewTouchUp="Element_TouchUp" Tag="{x:Static local:TouchValue.E4}" Fill="White" />
|
||||
<Polygon Canvas.Left="794" Canvas.Top="900" Points="0,0 97,0 133,36 134,68 134,138 124,143 88,158 48,175 10,191 6,190 -3,181 -11,174 -65,120 -66,112 -67,68 -4,5 0,0" PreviewTouchDown="Element_TouchDown" PreviewTouchMove="Element_TouchMove" PreviewTouchUp="Element_TouchUp" Tag="{x:Static local:TouchValue.B4}" Fill="White" />
|
||||
<Polygon Canvas.Left="720" Canvas.Top="1034" Points="0,0 4,2 97,95 91,102 2,191 -2,189 -35,156 -43,149 -87,105 -95,98 -97,95 -90,88 -82,81 -44,43 -36,36 0,0" PreviewTouchDown="Element_TouchDown" PreviewTouchMove="Element_TouchMove" PreviewTouchUp="Element_TouchUp" Tag="{x:Static local:TouchValue.E5}" Fill="White" />
|
||||
<Polygon Canvas.Left="550" Canvas.Top="899" Points="0,0 97,1 143,47 150,55 163,68 164,121 92,193 83,190 37,171 -4,154 -37,140 -37,101 -36,37 -24,25 -17,17 0,0" PreviewTouchDown="Element_TouchDown" PreviewTouchMove="Element_TouchMove" PreviewTouchUp="Element_TouchUp" Tag="{x:Static local:TouchValue.B5}" Fill="White" />
|
||||
<Polygon Canvas.Left="474" Canvas.Top="939" Points="0,0 25,0 25,137 -110,137 -111,53 -111,1 0,0" PreviewTouchDown="Element_TouchDown" PreviewTouchMove="Element_TouchMove" PreviewTouchUp="Element_TouchUp" Tag="{x:Static local:TouchValue.E6}" Fill="White" />
|
||||
<Polygon Canvas.Left="420" Canvas.Top="727" Points="0,0 52,0 119,67 119,162 109,172 102,180 82,200 -20,200 -38,158 -50,129 -68,86 -73,73 0,0" PreviewTouchDown="Element_TouchDown" PreviewTouchMove="Element_TouchMove" PreviewTouchUp="Element_TouchUp" Tag="{x:Static local:TouchValue.B6}" Fill="White" />
|
||||
<Polygon Canvas.Left="311" Canvas.Top="623" Points="0,0 4,2 61,59 69,66 97,94 91,101 2,190 -2,189 -51,140 -59,133 -96,96 -94,92 -71,69 -63,62 -25,24 -17,17 0,0" PreviewTouchDown="Element_TouchDown" PreviewTouchMove="Element_TouchMove" PreviewTouchUp="Element_TouchUp" Tag="{x:Static local:TouchValue.E7}" Fill="White" />
|
||||
<Polygon Canvas.Left="401" Canvas.Top="512" Points="0,0 102,0 124,22 132,29 140,37 140,69 139,130 133,138 101,170 94,178 72,200 20,201 -53,128 -50,119 -31,74 -12,29 0,0" PreviewTouchDown="Element_TouchDown" PreviewTouchMove="Element_TouchMove" PreviewTouchUp="Element_TouchUp" Tag="{x:Static local:TouchValue.B7}" Fill="White" />
|
||||
<Polygon Canvas.Left="491" Canvas.Top="361" Points="0,0 8,0 8,137 -127,137 -128,53 -128,1 0,0" PreviewTouchDown="Element_TouchDown" PreviewTouchMove="Element_TouchMove" PreviewTouchUp="Element_TouchUp" Tag="{x:Static local:TouchValue.E8}" Fill="White" />
|
||||
<Polygon Canvas.Left="640" Canvas.Top="348" Points="0,0 8,6 74,72 73,124 45,152 38,160 17,181 10,189 8,191 -90,191 -127,154 -126,50 -88,35 -20,8 0,0" PreviewTouchDown="Element_TouchDown" PreviewTouchMove="Element_TouchMove" PreviewTouchUp="Element_TouchUp" Tag="{x:Static local:TouchValue.B8}" Fill="White" />
|
||||
|
||||
<Polygon Canvas.Left="728" Canvas.Top="583" Points="0,0 51,0 65,14 72,22 129,79 129,193 100,222 93,230 65,258 58,266 50,274 10,273 0,272 0,0" PreviewTouchDown="Element_TouchDown" PreviewTouchMove="Element_TouchMove" PreviewTouchUp="Element_TouchUp" Tag="{x:Static local:TouchValue.C1}" Fill="White" />
|
||||
<Polygon Canvas.Left="662" Canvas.Top="583" Points="0,0 52,0 52,267 51,273 2,273 -78,193 -78,80 -47,49 -40,41 -5,6 0,0" PreviewTouchDown="Element_TouchDown" PreviewTouchMove="Element_TouchMove" PreviewTouchUp="Element_TouchUp" Tag="{x:Static local:TouchValue.C2}" Fill="White" />
|
||||
<Polygon Canvas.Left="714" Canvas.Top="583" Points="0,0 14,0 14,273 0,273 0,0" PreviewTouchDown="Element_TouchDown" PreviewTouchMove="Element_TouchMove" PreviewTouchUp="Element_TouchUp" Tag="{x:Static local:TouchValue.C3}" Fill="White" />
|
||||
|
||||
|
||||
|
||||
<Border x:Name="ResizeGrip"
|
||||
Width="150" Height="90" Background="White"
|
||||
MouseDown="ResizeGrip_MouseDown" Canvas.Left="1290" Canvas.Top="1350" HorizontalAlignment="Center" VerticalAlignment="Top">
|
||||
<Label FontSize="50" Content="{Binding LbTouchPanelResize}" d:Content="Resize" />
|
||||
</Border>
|
||||
|
||||
</Canvas>
|
||||
</Viewbox>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
</Border>
|
||||
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
using System.Runtime.InteropServices;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Interop;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Animation;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Shapes;
|
||||
using WpfMaiTouchEmulator.Managers;
|
||||
|
||||
namespace WpfMaiTouchEmulator;
|
||||
/// <summary>
|
||||
|
@ -12,11 +16,14 @@ public partial class TouchPanel : Window
|
|||
{
|
||||
internal Action<TouchValue>? onTouch;
|
||||
internal Action<TouchValue>? onRelease;
|
||||
internal Action? onInitialReposition;
|
||||
|
||||
private readonly Dictionary<int, Polygon> activeTouches = [];
|
||||
private readonly Dictionary<int, (Polygon polygon, Point lastPoint)> activeTouches = new();
|
||||
private readonly TouchPanelPositionManager _positionManager;
|
||||
private List<Polygon> buttons = [];
|
||||
private bool isDebugEnabled = Properties.Settings.Default.IsDebugEnabled;
|
||||
private bool isRingButtonEmulationEnabled = Properties.Settings.Default.IsRingButtonEmulationEnabled;
|
||||
private bool hasRepositioned = false;
|
||||
|
||||
private enum ResizeDirection
|
||||
{
|
||||
|
@ -30,35 +37,100 @@ public partial class TouchPanel : Window
|
|||
[DllImport("user32.dll", CharSet = CharSet.Auto)]
|
||||
private static extern int SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
|
||||
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct RECT
|
||||
{
|
||||
public int Left;
|
||||
public int Top;
|
||||
public int Right;
|
||||
public int Bottom;
|
||||
}
|
||||
|
||||
public enum SizingEdge
|
||||
{
|
||||
Left = 1,
|
||||
Right = 2,
|
||||
Top = 3,
|
||||
TopLeft = 4,
|
||||
TopRight = 5,
|
||||
Bottom = 6,
|
||||
BottomLeft = 7,
|
||||
BottomRight = 8
|
||||
}
|
||||
|
||||
private const double FixedAspectRatio = 720.0 / 1280.0; // width / height
|
||||
private const int MinWidth = 180;
|
||||
private const int MinHeight = 320;
|
||||
|
||||
public TouchPanel()
|
||||
{
|
||||
InitializeComponent();
|
||||
Topmost = true;
|
||||
_positionManager = new TouchPanelPositionManager();
|
||||
Loaded += Window_Loaded;
|
||||
|
||||
StateCheckLoop();
|
||||
Touch.FrameReported += OnTouchFrameReported;
|
||||
}
|
||||
|
||||
private async void StateCheckLoop()
|
||||
|
||||
protected override void OnSourceInitialized(EventArgs e)
|
||||
{
|
||||
while (true)
|
||||
base.OnSourceInitialized(e);
|
||||
var source = HwndSource.FromHwnd(new WindowInteropHelper(this).Handle);
|
||||
source.AddHook(WndProc);
|
||||
}
|
||||
|
||||
private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
|
||||
{
|
||||
const int WM_SIZING = 0x0214;
|
||||
if (msg == WM_SIZING)
|
||||
{
|
||||
if (activeTouches.Count != 0 && !TouchesOver.Any())
|
||||
{
|
||||
await Task.Delay(100);
|
||||
if (activeTouches.Count != 0 && !TouchesOver.Any())
|
||||
{
|
||||
DeselectAllItems();
|
||||
}
|
||||
}
|
||||
await Task.Delay(100);
|
||||
var rect = Marshal.PtrToStructure<RECT>(lParam);
|
||||
var edge = (SizingEdge)wParam.ToInt32();
|
||||
EnforceAspectRatio(ref rect, edge);
|
||||
Marshal.StructureToPtr(rect, lParam, true);
|
||||
handled = true;
|
||||
}
|
||||
return IntPtr.Zero;
|
||||
}
|
||||
|
||||
private void EnforceAspectRatio(ref RECT rect, SizingEdge edge)
|
||||
{
|
||||
var currentWidth = rect.Right - rect.Left;
|
||||
var currentHeight = rect.Bottom - rect.Top;
|
||||
int newWidth, newHeight;
|
||||
|
||||
if (edge == SizingEdge.BottomRight)
|
||||
{
|
||||
newWidth = (int)(currentHeight * FixedAspectRatio);
|
||||
newHeight = currentHeight;
|
||||
}
|
||||
else
|
||||
{
|
||||
newHeight = (int)(currentWidth / FixedAspectRatio);
|
||||
newWidth = currentWidth;
|
||||
}
|
||||
|
||||
// Enforce minimum size while keeping the aspect ratio.
|
||||
if (newWidth < MinWidth)
|
||||
{
|
||||
newWidth = MinWidth;
|
||||
newHeight = (int)(newWidth / FixedAspectRatio);
|
||||
}
|
||||
if (newHeight < MinHeight)
|
||||
{
|
||||
newHeight = MinHeight;
|
||||
newWidth = (int)(newHeight * FixedAspectRatio);
|
||||
}
|
||||
|
||||
rect.Right = rect.Left + newWidth;
|
||||
rect.Bottom = rect.Top + newHeight;
|
||||
}
|
||||
|
||||
private void Window_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
buttons = VisualTreeHelperExtensions.FindVisualChildren<Polygon>(this);
|
||||
DeselectAllItems();
|
||||
}
|
||||
|
||||
public void PositionTouchPanel()
|
||||
|
@ -73,6 +145,12 @@ public partial class TouchPanel : Window
|
|||
Left = position.Value.Left;
|
||||
Width = position.Value.Width;
|
||||
Height = position.Value.Height;
|
||||
|
||||
if (!hasRepositioned)
|
||||
{
|
||||
hasRepositioned = true;
|
||||
onInitialReposition?.Invoke();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -86,74 +164,111 @@ public partial class TouchPanel : Window
|
|||
{
|
||||
if (e.LeftButton == MouseButtonState.Pressed)
|
||||
{
|
||||
ResizeWindow(ResizeDirection.BottomRight);
|
||||
ResizeWindow(SizingEdge.BottomRight);
|
||||
}
|
||||
}
|
||||
|
||||
private void ResizeWindow(ResizeDirection direction)
|
||||
private void ResizeWindow(SizingEdge edge)
|
||||
{
|
||||
ReleaseCapture();
|
||||
SendMessage(new System.Windows.Interop.WindowInteropHelper(this).Handle,
|
||||
0x112, // WM_SYSCOMMAND message
|
||||
(IntPtr)(0xF000 + direction),
|
||||
IntPtr.Zero);
|
||||
SendMessage(new WindowInteropHelper(this).Handle, 0x112, (IntPtr)(0xF000 + (int)edge), IntPtr.Zero);
|
||||
}
|
||||
|
||||
private void Element_TouchDown(object sender, TouchEventArgs e)
|
||||
private void OnTouchFrameReported(object sender, TouchFrameEventArgs e)
|
||||
{
|
||||
// Cast the sender to a Border to ensure it's the correct element type.
|
||||
if (sender is Polygon element)
|
||||
{
|
||||
// Highlight the element and add it to the active touches tracking.
|
||||
HighlightElement(element, true);
|
||||
onTouch?.Invoke((TouchValue)element.Tag);
|
||||
activeTouches[e.TouchDevice.Id] = element;
|
||||
}
|
||||
e.Handled = true;
|
||||
}
|
||||
var currentTouchPoints = e.GetTouchPoints(this);
|
||||
var currentIds = new HashSet<int>();
|
||||
|
||||
private void Element_TouchMove(object sender, TouchEventArgs e)
|
||||
{
|
||||
// Attempt to find the element under the current touch point.
|
||||
var touchPoint = e.GetTouchPoint(this).Position;
|
||||
var hitTestResult = VisualTreeHelper.HitTest(this, touchPoint);
|
||||
if (hitTestResult != null && hitTestResult.VisualHit is Polygon newElement)
|
||||
foreach (var touch in currentTouchPoints)
|
||||
{
|
||||
// If this touch point is already tracking another element, unhighlight the previous one.
|
||||
if (activeTouches.TryGetValue(e.TouchDevice.Id, out var previousElement) && previousElement != newElement)
|
||||
var id = touch.TouchDevice.Id;
|
||||
|
||||
// If the touch is released, process it as a TouchUp.
|
||||
if (touch.Action == TouchAction.Up)
|
||||
{
|
||||
Task.Delay(50)
|
||||
.ContinueWith(t =>
|
||||
if (activeTouches.TryGetValue(id, out var touchInfo2))
|
||||
{
|
||||
if (activeTouches.Values.Count(v => v.polygon == touchInfo2.polygon) == 1)
|
||||
{
|
||||
HighlightElement(previousElement, false);
|
||||
Application.Current.Dispatcher.Invoke(() =>
|
||||
HighlightElement(touchInfo2.polygon, false);
|
||||
onRelease?.Invoke((TouchValue)touchInfo2.polygon.Tag);
|
||||
if (isRingButtonEmulationEnabled)
|
||||
{
|
||||
onRelease?.Invoke((TouchValue)previousElement.Tag);
|
||||
});
|
||||
});
|
||||
|
||||
RingButtonEmulator.ReleaseButton((TouchValue)touchInfo2.polygon.Tag);
|
||||
}
|
||||
}
|
||||
activeTouches.Remove(id);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// Highlight the new element and update the tracking.
|
||||
HighlightElement(newElement, true);
|
||||
onTouch?.Invoke((TouchValue)newElement.Tag);
|
||||
activeTouches[e.TouchDevice.Id] = newElement;
|
||||
currentIds.Add(id);
|
||||
|
||||
// New touch (TouchDown)
|
||||
if (!activeTouches.TryGetValue(id, out var touchInfo))
|
||||
{
|
||||
if (VisualTreeHelper.HitTest(this, touch.Position)?.VisualHit is Polygon polygon)
|
||||
{
|
||||
HighlightElement(polygon, true);
|
||||
activeTouches[id] = (polygon, touch.Position);
|
||||
onTouch?.Invoke((TouchValue)polygon.Tag);
|
||||
if (isRingButtonEmulationEnabled && RingButtonEmulator.HasRingButtonMapping((TouchValue)polygon.Tag))
|
||||
{
|
||||
RingButtonEmulator.PressButton((TouchValue)polygon.Tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Existing touch (TouchMove)
|
||||
else
|
||||
{
|
||||
var previousPosition = touchInfo.lastPoint;
|
||||
var currentPosition = touch.Position;
|
||||
var sampleCount = 10;
|
||||
var changed = false;
|
||||
|
||||
for (var i = 1; i <= sampleCount; i++)
|
||||
{
|
||||
var t = (double)i / sampleCount;
|
||||
var samplePoint = new Point(
|
||||
previousPosition.X + (currentPosition.X - previousPosition.X) * t,
|
||||
previousPosition.Y + (currentPosition.Y - previousPosition.Y) * t);
|
||||
if (VisualTreeHelper.HitTest(this, samplePoint)?.VisualHit is Polygon polygon && polygon != touchInfo.polygon)
|
||||
{
|
||||
if (activeTouches.Values.Count(v => v.polygon == touchInfo.polygon) == 1)
|
||||
{
|
||||
HighlightElement(touchInfo.polygon, false);
|
||||
onRelease?.Invoke((TouchValue)touchInfo.polygon.Tag);
|
||||
}
|
||||
HighlightElement(polygon, true);
|
||||
onTouch?.Invoke((TouchValue)polygon.Tag);
|
||||
activeTouches[id] = (polygon, samplePoint);
|
||||
changed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!changed)
|
||||
{
|
||||
activeTouches[id] = (touchInfo.polygon, currentPosition);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
private void Element_TouchUp(object sender, TouchEventArgs e)
|
||||
{
|
||||
// When touch is lifted, unhighlight the associated element and remove it from tracking.
|
||||
if (activeTouches.TryGetValue(e.TouchDevice.Id, out var element))
|
||||
// Process any touches that might not be reported this frame.
|
||||
var endedTouches = activeTouches.Keys.Except(currentIds).ToList();
|
||||
foreach (var id in endedTouches)
|
||||
{
|
||||
HighlightElement(element, false);
|
||||
onRelease?.Invoke((TouchValue)element.Tag);
|
||||
activeTouches.Remove(e.TouchDevice.Id);
|
||||
var touchInfo = activeTouches[id];
|
||||
if (activeTouches.Values.Count(v => v.polygon == touchInfo.polygon) == 1)
|
||||
{
|
||||
HighlightElement(touchInfo.polygon, false);
|
||||
onRelease?.Invoke((TouchValue)touchInfo.polygon.Tag);
|
||||
if (isRingButtonEmulationEnabled)
|
||||
{
|
||||
RingButtonEmulator.ReleaseButton((TouchValue)touchInfo.polygon.Tag);
|
||||
}
|
||||
}
|
||||
activeTouches.Remove(id);
|
||||
}
|
||||
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
private void DeselectAllItems()
|
||||
|
@ -161,10 +276,11 @@ public partial class TouchPanel : Window
|
|||
// Logic to deselect all items or the last touched item
|
||||
foreach (var element in activeTouches.Values)
|
||||
{
|
||||
HighlightElement(element, false);
|
||||
onRelease?.Invoke((TouchValue)element.Tag);
|
||||
HighlightElement(element.polygon, false);
|
||||
onRelease?.Invoke((TouchValue)element.polygon.Tag);
|
||||
}
|
||||
activeTouches.Clear();
|
||||
RingButtonEmulator.ReleaseAllButtons();
|
||||
}
|
||||
|
||||
public void SetDebugMode(bool enabled)
|
||||
|
@ -176,6 +292,434 @@ public partial class TouchPanel : Window
|
|||
});
|
||||
}
|
||||
|
||||
public void SetLargeButtonMode(bool enabled)
|
||||
{
|
||||
TouchValue[] ringButtonsValues = {
|
||||
TouchValue.A1,
|
||||
TouchValue.A2,
|
||||
TouchValue.A3,
|
||||
TouchValue.A4,
|
||||
TouchValue.A5,
|
||||
TouchValue.A6,
|
||||
TouchValue.A7,
|
||||
TouchValue.A8,
|
||||
TouchValue.D1,
|
||||
TouchValue.D2,
|
||||
TouchValue.D3,
|
||||
TouchValue.D4,
|
||||
TouchValue.D5,
|
||||
TouchValue.D6,
|
||||
TouchValue.D7,
|
||||
TouchValue.D8,
|
||||
};
|
||||
|
||||
var a1 = buttons.First(button => (TouchValue)button.Tag == TouchValue.A1);
|
||||
var a2 = buttons.First(button => (TouchValue)button.Tag == TouchValue.A2);
|
||||
var a3 = buttons.First(button => (TouchValue)button.Tag == TouchValue.A3);
|
||||
var a4 = buttons.First(button => (TouchValue)button.Tag == TouchValue.A4);
|
||||
var a5 = buttons.First(button => (TouchValue)button.Tag == TouchValue.A5);
|
||||
var a6 = buttons.First(button => (TouchValue)button.Tag == TouchValue.A6);
|
||||
var a7 = buttons.First(button => (TouchValue)button.Tag == TouchValue.A7);
|
||||
var a8 = buttons.First(button => (TouchValue)button.Tag == TouchValue.A8);
|
||||
var d1 = buttons.First(button => (TouchValue)button.Tag == TouchValue.D1);
|
||||
var d2 = buttons.First(button => (TouchValue)button.Tag == TouchValue.D2);
|
||||
var d3 = buttons.First(button => (TouchValue)button.Tag == TouchValue.D3);
|
||||
var d4 = buttons.First(button => (TouchValue)button.Tag == TouchValue.D4);
|
||||
var d5 = buttons.First(button => (TouchValue)button.Tag == TouchValue.D5);
|
||||
var d6 = buttons.First(button => (TouchValue)button.Tag == TouchValue.D6);
|
||||
var d7 = buttons.First(button => (TouchValue)button.Tag == TouchValue.D7);
|
||||
var d8 = buttons.First(button => (TouchValue)button.Tag == TouchValue.D8);
|
||||
|
||||
if (enabled)
|
||||
{
|
||||
d1.Points = new PointCollection
|
||||
{
|
||||
new Point(-5, -50),
|
||||
new Point(205, -50),
|
||||
new Point(165, 253),
|
||||
new Point(100, 188),
|
||||
new Point(35, 253),
|
||||
};
|
||||
|
||||
a1.Points = new PointCollection
|
||||
{
|
||||
new Point(495, -50),
|
||||
new Point(208, 338),
|
||||
new Point(145, 338),
|
||||
new Point(49, 297),
|
||||
new Point(0, 249),
|
||||
new Point(42, -55),
|
||||
};
|
||||
d2.Points = new PointCollection
|
||||
{
|
||||
new Point(290, -182),
|
||||
new Point(500, -180),
|
||||
new Point(500, -5),
|
||||
new Point(96, 297),
|
||||
new Point(96, 205),
|
||||
new Point(0, 205),
|
||||
};
|
||||
a2.Points = new PointCollection
|
||||
{
|
||||
new Point(405, 317),
|
||||
new Point(91, 362),
|
||||
new Point(42, 314),
|
||||
new Point(0, 219),
|
||||
new Point(0, 150),
|
||||
new Point(405, -150),
|
||||
};
|
||||
d3.Points = new PointCollection
|
||||
{
|
||||
new Point(315, -10),
|
||||
new Point(315, 208),
|
||||
new Point(0, 165),
|
||||
new Point(65, 100),
|
||||
new Point(0, 35),
|
||||
};
|
||||
a3.Points = new PointCollection
|
||||
{
|
||||
new Point(406, 520),
|
||||
new Point(0, 213),
|
||||
new Point(0, 144),
|
||||
new Point(41, 48),
|
||||
new Point(89, 0),
|
||||
new Point(406, 43),
|
||||
};
|
||||
d4.Points = new PointCollection
|
||||
{
|
||||
new Point(500, 309),
|
||||
new Point(500, 491),
|
||||
new Point(305, 491),
|
||||
new Point(0, 92),
|
||||
new Point(92, 92),
|
||||
new Point(92, 0),
|
||||
};
|
||||
a4.Points = new PointCollection
|
||||
{
|
||||
new Point(45, 400),
|
||||
new Point(0, 83),
|
||||
new Point(48, 35),
|
||||
new Point(144, 0),
|
||||
new Point(212, 0),
|
||||
new Point(515, 400),
|
||||
};
|
||||
d5.Points = new PointCollection
|
||||
{
|
||||
new Point(208, 317),
|
||||
new Point(-10, 317),
|
||||
new Point(34, 0),
|
||||
new Point(99, 65),
|
||||
new Point(164, 0),
|
||||
};
|
||||
|
||||
a5.Points = new PointCollection
|
||||
{
|
||||
new Point(317, 400),
|
||||
new Point(363, 83),
|
||||
new Point(316, 35),
|
||||
new Point(220, 0),
|
||||
new Point(152, 0),
|
||||
new Point(-150, 400),
|
||||
};
|
||||
d6.Points = new PointCollection
|
||||
{
|
||||
new Point(-10, 492),
|
||||
new Point(-200, 492),
|
||||
new Point(-200, 295),
|
||||
new Point(199, 0),
|
||||
new Point(199, 92),
|
||||
new Point(291, 92),
|
||||
};
|
||||
a6.Points = new PointCollection
|
||||
{
|
||||
new Point(-67, 505),
|
||||
new Point(333, 214),
|
||||
new Point(333, 144),
|
||||
new Point(296, 48),
|
||||
new Point(248, 0),
|
||||
new Point(-67, 45),
|
||||
};
|
||||
|
||||
d7.Points = new PointCollection
|
||||
{
|
||||
new Point(-60, 207),
|
||||
new Point(-60, -7),
|
||||
new Point(253, 34),
|
||||
new Point(188, 99),
|
||||
new Point(253, 164),
|
||||
};
|
||||
|
||||
a7.Points = new PointCollection
|
||||
{
|
||||
new Point(-65, 320),
|
||||
new Point(248, 362),
|
||||
new Point(297, 314),
|
||||
new Point(333, 219),
|
||||
new Point(333, 151),
|
||||
new Point(-65, -150),
|
||||
};
|
||||
d8.Points = new PointCollection
|
||||
{
|
||||
new Point(-195, -10),
|
||||
new Point(-195, -195),
|
||||
new Point(-5, -195),
|
||||
new Point(298, 199),
|
||||
new Point(200, 199),
|
||||
new Point(200, 291),
|
||||
};
|
||||
|
||||
a8.Points = new PointCollection
|
||||
{
|
||||
new Point(-148, -55),
|
||||
new Point(153, 338),
|
||||
new Point(215, 338),
|
||||
new Point(311, 297),
|
||||
new Point(359, 249),
|
||||
new Point(318, -55),
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
d1.Points = new PointCollection
|
||||
{
|
||||
new Point(0, 5),
|
||||
new Point(50, 2),
|
||||
new Point(100, 0),
|
||||
new Point(150, 2),
|
||||
new Point(200, 5),
|
||||
new Point(165, 253),
|
||||
new Point(100, 188),
|
||||
new Point(35, 253),
|
||||
};
|
||||
|
||||
a1.Points = new PointCollection
|
||||
{
|
||||
new Point(150, 28),
|
||||
new Point(245, 65),
|
||||
new Point(360, 133),
|
||||
new Point(208, 338),
|
||||
new Point(145, 338),
|
||||
new Point(49, 297),
|
||||
new Point(0, 249),
|
||||
new Point(35, 0),
|
||||
};
|
||||
|
||||
d2.Points = new PointCollection
|
||||
{
|
||||
new Point(153, 0),
|
||||
new Point(187, 32),
|
||||
new Point(225, 67),
|
||||
new Point(259, 104),
|
||||
new Point(295, 147),
|
||||
new Point(96, 297),
|
||||
new Point(96, 205),
|
||||
new Point(0, 205),
|
||||
};
|
||||
|
||||
a2.Points = new PointCollection
|
||||
{
|
||||
new Point(261, 101),
|
||||
new Point(303, 195),
|
||||
new Point(339, 327),
|
||||
new Point(91, 362),
|
||||
new Point(42, 314),
|
||||
new Point(0, 219),
|
||||
new Point(0, 150),
|
||||
new Point(202, 0),
|
||||
};
|
||||
|
||||
d3.Points = new PointCollection
|
||||
{
|
||||
new Point(248, 0),
|
||||
new Point(251, 48),
|
||||
new Point(253, 100),
|
||||
new Point(251, 150),
|
||||
new Point(247, 199),
|
||||
new Point(0, 165),
|
||||
new Point(65, 100),
|
||||
new Point(0, 35),
|
||||
};
|
||||
|
||||
a3.Points = new PointCollection
|
||||
{
|
||||
new Point(305, 150),
|
||||
new Point(269, 246),
|
||||
new Point(201, 364),
|
||||
new Point(0, 213),
|
||||
new Point(0, 144),
|
||||
new Point(41, 48),
|
||||
new Point(89, 0),
|
||||
new Point(337, 34),
|
||||
};
|
||||
|
||||
d4.Points = new PointCollection
|
||||
{
|
||||
new Point(292, 151),
|
||||
new Point(260, 187),
|
||||
new Point(225, 225),
|
||||
new Point(188, 259),
|
||||
new Point(151, 291),
|
||||
new Point(0, 92),
|
||||
new Point(92, 92),
|
||||
new Point(92, 0),
|
||||
};
|
||||
|
||||
a4.Points = new PointCollection
|
||||
{
|
||||
new Point(260, 259),
|
||||
new Point(167, 301),
|
||||
new Point(37, 335),
|
||||
new Point(0, 83),
|
||||
new Point(48, 35),
|
||||
new Point(144, 0),
|
||||
new Point(212, 0),
|
||||
new Point(364, 200),
|
||||
};
|
||||
|
||||
d5.Points = new PointCollection
|
||||
{
|
||||
new Point(199, 252),
|
||||
new Point(151, 255),
|
||||
new Point(99, 257),
|
||||
new Point(49, 255),
|
||||
new Point(0, 252),
|
||||
new Point(34, 0),
|
||||
new Point(99, 65),
|
||||
new Point(164, 0),
|
||||
};
|
||||
|
||||
a5.Points = new PointCollection
|
||||
{
|
||||
new Point(104, 259),
|
||||
new Point(197, 301),
|
||||
new Point(327, 335),
|
||||
new Point(363, 83),
|
||||
new Point(316, 35),
|
||||
new Point(220, 0),
|
||||
new Point(152, 0),
|
||||
new Point(0, 201),
|
||||
};
|
||||
|
||||
d6.Points = new PointCollection
|
||||
{
|
||||
new Point(140, 292),
|
||||
new Point(104, 260),
|
||||
new Point(66, 225),
|
||||
new Point(32, 188),
|
||||
new Point(0, 151),
|
||||
new Point(199, 0),
|
||||
new Point(199, 92),
|
||||
new Point(291, 92),
|
||||
};
|
||||
|
||||
a6.Points = new PointCollection
|
||||
{
|
||||
new Point(32, 150),
|
||||
new Point(68, 246),
|
||||
new Point(133, 365),
|
||||
new Point(333, 214),
|
||||
new Point(333, 144),
|
||||
new Point(296, 48),
|
||||
new Point(248, 0),
|
||||
new Point(0, 35),
|
||||
};
|
||||
|
||||
d7.Points = new PointCollection
|
||||
{
|
||||
new Point(5, 199),
|
||||
new Point(2, 151),
|
||||
new Point(0, 99),
|
||||
new Point(2, 49),
|
||||
new Point(6, 0),
|
||||
new Point(253, 34),
|
||||
new Point(188, 99),
|
||||
new Point(253, 164),
|
||||
};
|
||||
|
||||
a7.Points = new PointCollection
|
||||
{
|
||||
new Point(78, 101),
|
||||
new Point(36, 195),
|
||||
new Point(0, 327),
|
||||
new Point(248, 362),
|
||||
new Point(297, 314),
|
||||
new Point(333, 219),
|
||||
new Point(333, 151),
|
||||
new Point(132, 0),
|
||||
};
|
||||
|
||||
d8.Points = new PointCollection
|
||||
{
|
||||
new Point(0, 140),
|
||||
new Point(32, 104),
|
||||
new Point(67, 66),
|
||||
new Point(104, 32),
|
||||
new Point(145, 0),
|
||||
new Point(298, 199),
|
||||
new Point(200, 199),
|
||||
new Point(200, 291),
|
||||
};
|
||||
|
||||
a8.Points = new PointCollection
|
||||
{
|
||||
new Point(210, 28),
|
||||
new Point(115, 65),
|
||||
new Point(0, 138),
|
||||
new Point(153, 338),
|
||||
new Point(215, 338),
|
||||
new Point(311, 297),
|
||||
new Point(359, 249),
|
||||
new Point(324, 0),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public void SetBorderMode(BorderSetting borderSetting, string borderColour)
|
||||
{
|
||||
if (borderSetting == BorderSetting.Rainbow)
|
||||
{
|
||||
var rotateTransform = new RotateTransform { CenterX = 0.5, CenterY = 0.5 };
|
||||
touchPanelBorder.BorderBrush = new ImageBrush {
|
||||
ImageSource = new BitmapImage(new Uri(@"pack://application:,,,/Assets/conicalGradient.png")),
|
||||
ViewportUnits = BrushMappingMode.RelativeToBoundingBox,
|
||||
Viewport = new Rect(0, 0, 1, 1),
|
||||
TileMode = TileMode.Tile,
|
||||
RelativeTransform = rotateTransform,
|
||||
};
|
||||
|
||||
var animation = new DoubleAnimation
|
||||
{
|
||||
From = 0,
|
||||
To = 360,
|
||||
Duration = new Duration(TimeSpan.FromSeconds(10)),
|
||||
RepeatBehavior = RepeatBehavior.Forever
|
||||
};
|
||||
|
||||
rotateTransform.BeginAnimation(RotateTransform.AngleProperty, animation);
|
||||
return;
|
||||
}
|
||||
else if (borderSetting == BorderSetting.Solid)
|
||||
{
|
||||
try
|
||||
{
|
||||
var colour = (Color)ColorConverter.ConvertFromString(borderColour);
|
||||
touchPanelBorder.BorderBrush = new SolidColorBrush { Color = colour };
|
||||
return;
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error("Failed to parse solid colour", ex);
|
||||
}
|
||||
}
|
||||
touchPanelBorder.BorderBrush = null;
|
||||
}
|
||||
|
||||
public void SetEmulateRingButton(bool enabled)
|
||||
{
|
||||
isRingButtonEmulationEnabled = enabled;
|
||||
}
|
||||
|
||||
private void HighlightElement(Polygon element, bool highlight)
|
||||
{
|
||||
if (isDebugEnabled)
|
||||
|
|
|
@ -2,15 +2,32 @@
|
|||
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>net8.0-windows</TargetFramework>
|
||||
<TargetFramework>net8.0-windows10.0.17763.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<UseWPF>true</UseWPF>
|
||||
<ApplicationIcon>Assets\icon.ico</ApplicationIcon>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="System.Drawing.Common" Version="8.0.1" />
|
||||
<PackageReference Include="System.IO.Ports" Version="8.0.0" />
|
||||
<None Remove="Assets\conicalGradient.png" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="Assets\icon.ico" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="System.Drawing.Common" Version="9.0.0" />
|
||||
<PackageReference Include="System.IO.Ports" Version="9.0.0" />
|
||||
<PackageReference Include="WPF-UI" Version="3.0.5" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Resource Include="Assets\conicalGradient.png">
|
||||
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||
</Resource>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
Loading…
Reference in New Issue