Compare commits
265 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0c3938b652 | |||
| 16f80adb0d | |||
| 637b6bb4f9 | |||
| 12e91927a5 | |||
| 8f6f22ba7f | |||
| b520d6a334 | |||
| b7bff30445 | |||
| 0d790bbd80 | |||
| 8394e99127 | |||
| 16ae32bfd7 | |||
| cc6423e384 | |||
| 06cc587599 | |||
| 9d36088f1d | |||
| f9f73b015c | |||
| 77ffd696bb | |||
| bdb8bed053 | |||
| 4b17c8e96e | |||
| 8109711f4e | |||
| 327eba3fa7 | |||
| f3dccb2e99 | |||
| 7112d58e7c | |||
| 6e0aad853c | |||
| c64b1d0846 | |||
| 6eba16ce99 | |||
| 2f6f719843 | |||
| f34bac49e4 | |||
| 39cdc6231f | |||
| 745e24da70 | |||
| a4f4f4fb15 | |||
| 3833c229c6 | |||
| 3dc3e9b5a8 | |||
| 12eeb79e9f | |||
| e08c84f70d | |||
| 10f55d5b65 | |||
| 761992d089 | |||
| 991a823700 | |||
| 61dbcf762c | |||
| 60b0149a9c | |||
| 501c034cfa | |||
| 11593db23c | |||
| a9ae2a004f | |||
| 7b2a31781c | |||
| ab73eb9632 | |||
| 8ade170b4e | |||
| 91c3d1161d | |||
| bb63805e87 | |||
| 8caf04990c | |||
| f28dd0a965 | |||
| b5d83268e5 | |||
| 19adc42122 | |||
| 8afee913be | |||
| 82d101365f | |||
| 73e679f268 | |||
| 372a8a1de1 | |||
| 171cc34c91 | |||
| fbd217d674 | |||
| f24960ab26 | |||
| d1a871c8f6 | |||
| 086b97906b | |||
| db76a11347 | |||
| 729b10cce8 | |||
| 4cbd25ccb3 | |||
| 0ef7b738a9 | |||
| 33b5563601 | |||
| f6f799f534 | |||
| 8c3f1360e1 | |||
| fafbabd603 | |||
| 254e38895c | |||
| aa0bb22cdd | |||
| 5bfd0c7b2f | |||
| c3885c170c | |||
| 88a7cce269 | |||
| a1fccc2905 | |||
| a889041896 | |||
| 8d778aba2c | |||
| ba5db63e0b | |||
| 0259d83429 | |||
| b6999e57ae | |||
| 04184cf731 | |||
| 04f98eb9e7 | |||
| 869dd045af | |||
| 339ebb862e | |||
| 7b8598bf9f | |||
| ab1c460225 | |||
| 298164d6ed | |||
| 703a8a4e0d | |||
| deaf5fcbf6 | |||
| 18b46689f1 | |||
| edbe3f8311 | |||
| 94c4c3e2d4 | |||
| 077f72737d | |||
| ae089a9390 | |||
| 0f087c2aa6 | |||
| 19d2ffb48e | |||
| a9bb6f73de | |||
| ca124732fa | |||
| 11da14aeab | |||
| 7d5f037c85 | |||
| f62b415227 | |||
| f2b8d4014e | |||
| 3ef047fb41 | |||
| aa3be4ab0d | |||
| 7500049ea2 | |||
| 44600df75c | |||
| dec2a15773 | |||
| 4da78a04cb | |||
| 98ec204bab | |||
| cd9499b064 | |||
| f5e824be86 | |||
| c76254f4f9 | |||
| 77ac6f88ca | |||
| 7e10911991 | |||
| 161b67b09d | |||
| 9614536a29 | |||
| 8ba7aab468 | |||
| 4ea9f79de1 | |||
| b7f7025d97 | |||
| 20d5dd2668 | |||
| adc2d02fbb | |||
| ef2dbdc93b | |||
| 9721ec1f0b | |||
| 4d069d87d7 | |||
| 0308f9ce65 | |||
| 6bcd3cb217 | |||
| 7f83c490db | |||
| bbf9c895b8 | |||
| ffa2063c52 | |||
| d464b1f78e | |||
| 92cb071408 | |||
| 9141b60d03 | |||
| df0a196931 | |||
| a8cb1dd495 | |||
| adc4966d49 | |||
| 1b2ea8c522 | |||
| 7c8bdb489b | |||
| 16458fbb42 | |||
| c72839cdcb | |||
| a31ad5803c | |||
| cf800cbd36 | |||
| 3c06ef0b1a | |||
| 2c3b921f09 | |||
| 402ecc66ae | |||
| e25f56a9b5 | |||
| b28fa887a2 | |||
| f83a02e619 | |||
| eaad089d68 | |||
| a2fda16df9 | |||
| e9e8ff57ae | |||
| 1fd95a2f2e | |||
| 228584ee48 | |||
| c651df0f6e | |||
| 5cced9baf2 | |||
| 5dd26e554b | |||
| 696fd3e8cd | |||
| 1d19b705d3 | |||
| d54074cb57 | |||
| cc054aeb75 | |||
| c32eaed534 | |||
| fa23f73ec4 | |||
| fbf6a13f92 | |||
| 3eba662772 | |||
| e007ee271f | |||
| 59a8d65a89 | |||
| 793519ae1b | |||
| 5c44062aa2 | |||
| fe03a2c2c0 | |||
| d1d74a3770 | |||
| 16108bf779 | |||
| 5bebf077e4 | |||
| efcc01ad6b | |||
| e8a4b45446 | |||
| 6cba297d77 | |||
| b149dc3cb9 | |||
| 1ee4f934b9 | |||
| f7b4adb85d | |||
| da3c41567d | |||
| 5f73795220 | |||
| 36bf1122c6 | |||
| 402f8bb9f9 | |||
| eef2a915fa | |||
| 26ee4d172f | |||
| 08eb450446 | |||
| ecae7d818c | |||
| 47ffccff68 | |||
| 0ba5286c94 | |||
| db8e1e3589 | |||
| d0764a6a77 | |||
| 7b6c347d6b | |||
| d58fec180c | |||
| ac4e4877a1 | |||
| ddea61245d | |||
| 98915bcff2 | |||
| 8e0f0450df | |||
| 1d9a669829 | |||
| 97bcf168b7 | |||
| e81198165b | |||
| b03b8da586 | |||
| d497e07187 | |||
| f284a99194 | |||
| 7d6dd6f805 | |||
| d70e28d198 | |||
| 4c6f138e5c | |||
| 5974841a7b | |||
| 5df54439ba | |||
| 8f627c6b7f | |||
| 3f28bc5c6c | |||
| 903fa699ca | |||
| d9e8f64699 | |||
| 8ad6ca8d41 | |||
| 4017efc65e | |||
| 6ed15d52de | |||
| 5246a2f79b | |||
| b670932dd7 | |||
| ddf30bd96b | |||
| 7e92428485 | |||
| 4c16050c85 | |||
| 2ed035525a | |||
| 1b89b0d7b6 | |||
| 0364821f0b | |||
| fa9d6f37ae | |||
| a4777904b9 | |||
| 0b3c2f95c5 | |||
| 8f54955432 | |||
| 034db2fc27 | |||
| 59141b0241 | |||
| 2e43b96a2c | |||
| edff96299c | |||
| 8d9587b790 | |||
| ad0cf2a849 | |||
| f928946c61 | |||
| 6cc9d0bee2 | |||
| 287e6bb91f | |||
| 3509036d85 | |||
| 752901dbb9 | |||
| e3add94546 | |||
| 8d31c74b39 | |||
| e6f608d206 | |||
| d80b9e29a7 | |||
| 092674465d | |||
| b2e3a5bb18 | |||
| 147a2f957e | |||
| ce56f2919c | |||
| 18059102a3 | |||
| 4542fcccbb | |||
| d12009d30c | |||
| d85e0fbd13 | |||
| f7a5f9ae6b | |||
| 3d4c3d0acc | |||
| c106c41048 | |||
| cea777e8b2 | |||
| 6f069b73da | |||
| c80af8c984 | |||
| d51cbd0682 | |||
| 7e94c945ff | |||
| bd9095b4c2 | |||
| c135bf8fb8 | |||
| f6aebb15b4 | |||
| 2b4f88becd | |||
| 7fbd3639b6 | |||
| 9e52c2c31d | |||
| 46a1e5ff14 | |||
| fa7c1fd646 | |||
| c347809eea | |||
| dd09a42f02 | |||
| db8ffd05ea |
@@ -89,6 +89,15 @@
|
||||
"contributions": [
|
||||
"design"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "Tayasui-rainnya",
|
||||
"name": "tayasui rainnya!",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/156585442?v=4",
|
||||
"profile": "https://github.com/Tayasui-rainnya",
|
||||
"contributions": [
|
||||
"design"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -0,0 +1,302 @@
|
||||
name: Pre-release and Changelog
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
version_type:
|
||||
description: 'Version bump type'
|
||||
required: true
|
||||
default: 'patch'
|
||||
type: choice
|
||||
options:
|
||||
- patch
|
||||
- minor
|
||||
- major
|
||||
prerelease:
|
||||
description: 'Create as pre-release'
|
||||
required: true
|
||||
default: true
|
||||
type: boolean
|
||||
|
||||
jobs:
|
||||
prerelease:
|
||||
if: github.ref == 'refs/heads/main'
|
||||
runs-on: windows-latest
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4.2.2
|
||||
with:
|
||||
fetch-depth: 0 # 获取所有历史记录用于生成changelog
|
||||
|
||||
- name: Setup MSbuild
|
||||
uses: microsoft/setup-msbuild@v2
|
||||
|
||||
- name: Setup NuGet
|
||||
uses: NuGet/setup-nuget@v2.0.1
|
||||
|
||||
- name: Restore NuGet Packages
|
||||
run: nuget restore "Ink Canvas.sln"
|
||||
|
||||
- name: Get current version from Git tag
|
||||
id: get_version
|
||||
run: |
|
||||
# 获取最新的tag
|
||||
$latestTag = git describe --tags --abbrev=0 2>$null
|
||||
if ($latestTag) {
|
||||
# 移除v前缀(如果有的话)
|
||||
$version = $latestTag -replace "^v", ""
|
||||
echo "Found latest tag: $latestTag"
|
||||
} else {
|
||||
# 如果没有tag,使用默认版本
|
||||
$version = "1.0.0"
|
||||
echo "No tags found, using default version"
|
||||
}
|
||||
echo "current_version=$version" >> $env:GITHUB_OUTPUT
|
||||
echo "Current version: $version"
|
||||
|
||||
- name: Calculate new version
|
||||
id: calc_version
|
||||
run: |
|
||||
$currentVersion = "${{ steps.get_version.outputs.current_version }}"
|
||||
$versionParts = $currentVersion.Split('.')
|
||||
|
||||
# 确保版本号格式正确(至少3部分)
|
||||
if ($versionParts.Length -ge 3) {
|
||||
$major = [int]$versionParts[0]
|
||||
$minor = [int]$versionParts[1]
|
||||
$patch = [int]$versionParts[2]
|
||||
} else {
|
||||
# 如果版本号格式不正确,使用默认值
|
||||
$major = 1
|
||||
$minor = 0
|
||||
$patch = 0
|
||||
}
|
||||
|
||||
$versionType = "${{ github.event.inputs.version_type }}"
|
||||
|
||||
switch ($versionType) {
|
||||
"major" {
|
||||
$major++
|
||||
$minor = 0
|
||||
$patch = 0
|
||||
}
|
||||
"minor" {
|
||||
$minor++
|
||||
$patch = 0
|
||||
}
|
||||
"patch" {
|
||||
$patch++
|
||||
}
|
||||
}
|
||||
|
||||
# 生成新版本号(保持3位格式,如1.7.13)
|
||||
$newVersion = "$major.$minor.$patch"
|
||||
echo "new_version=$newVersion" >> $env:GITHUB_OUTPUT
|
||||
echo "New version: $newVersion"
|
||||
|
||||
- name: Generate Changelog
|
||||
id: changelog
|
||||
run: |
|
||||
# 获取上次tag到现在的所有commit
|
||||
$lastTag = git describe --tags --abbrev=0 2>$null
|
||||
if ($lastTag) {
|
||||
$commits = git log --pretty=format:"%h|%s|%an|%ad" --date=short "$lastTag..HEAD"
|
||||
} else {
|
||||
$commits = git log --pretty=format:"%h|%s|%an|%ad" --date=short
|
||||
}
|
||||
|
||||
# 初始化分类数组
|
||||
$fixes = @()
|
||||
$improvements = @()
|
||||
$additions = @()
|
||||
$deletions = @()
|
||||
$versionChanges = @()
|
||||
$others = @()
|
||||
|
||||
# 解析每个commit
|
||||
foreach ($commit in $commits) {
|
||||
if ($commit -match "^([^|]+)\|([^|]+)\|([^|]+)\|([^|]+)$") {
|
||||
$hash = $matches[1]
|
||||
$message = $matches[2]
|
||||
$author = $matches[3]
|
||||
$date = $matches[4]
|
||||
|
||||
$commitInfo = @{
|
||||
Hash = $hash
|
||||
Message = $message
|
||||
Author = $author
|
||||
Date = $date
|
||||
}
|
||||
|
||||
# 根据commit消息分类
|
||||
if ($message -match "^(fix|修复)") {
|
||||
$fixes += $commitInfo
|
||||
} elseif ($message -match "^(improve|改进|优化)") {
|
||||
$improvements += $commitInfo
|
||||
} elseif ($message -match "^(add|新增|添加)") {
|
||||
$additions += $commitInfo
|
||||
} elseif ($message -match "^(delete|删除|移除)") {
|
||||
$deletions += $commitInfo
|
||||
} elseif ($message -match "(版本|version|更新版本号)") {
|
||||
$versionChanges += $commitInfo
|
||||
} else {
|
||||
$others += $commitInfo
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# 生成changelog内容
|
||||
$version = "${{ steps.calc_version.outputs.new_version }}"
|
||||
$changelog = "# ICC CE $version.0 更新日志`n`n## 修复 (Fixes)"
|
||||
|
||||
if ($fixes.Count -gt 0) {
|
||||
foreach ($fix in $fixes) {
|
||||
$changelog += "`n- $($fix.Message) ($($fix.Author), $($fix.Date))"
|
||||
}
|
||||
} else {
|
||||
$changelog += "`n- 无"
|
||||
}
|
||||
|
||||
$changelog += "`n`n## 改进 (Improvements)"
|
||||
|
||||
if ($improvements.Count -gt 0) {
|
||||
foreach ($improvement in $improvements) {
|
||||
$changelog += "`n- $($improvement.Message) ($($improvement.Author), $($improvement.Date))"
|
||||
}
|
||||
} else {
|
||||
$changelog += "`n- 无"
|
||||
}
|
||||
|
||||
$changelog += "`n`n## 新增功能 (New Features)"
|
||||
|
||||
if ($additions.Count -gt 0) {
|
||||
foreach ($addition in $additions) {
|
||||
$changelog += "`n- $($addition.Message) ($($addition.Author), $($addition.Date))"
|
||||
}
|
||||
} else {
|
||||
$changelog += "`n- 无"
|
||||
}
|
||||
|
||||
$changelog += "`n`n## 删除功能 (Removed Features)"
|
||||
|
||||
if ($deletions.Count -gt 0) {
|
||||
foreach ($deletion in $deletions) {
|
||||
$changelog += "`n- $($deletion.Message) ($($deletion.Author), $($deletion.Date))"
|
||||
}
|
||||
} else {
|
||||
$changelog += "`n- 无"
|
||||
}
|
||||
|
||||
$changelog += "`n`n## 版本更新 (Version Updates)"
|
||||
|
||||
if ($versionChanges.Count -gt 0) {
|
||||
foreach ($versionChange in $versionChanges) {
|
||||
$changelog += "`n- $($versionChange.Message) ($($versionChange.Author), $($versionChange.Date))"
|
||||
}
|
||||
} else {
|
||||
$changelog += "`n- 无"
|
||||
}
|
||||
|
||||
$changelog += "`n`n## 其他更改 (Other Changes)"
|
||||
|
||||
if ($others.Count -gt 0) {
|
||||
foreach ($other in $others) {
|
||||
$changelog += "`n- $($other.Message) ($($other.Author), $($other.Date))"
|
||||
}
|
||||
} else {
|
||||
$changelog += "`n- 无"
|
||||
}
|
||||
|
||||
$changelog += "`n`n---`n*此更新日志由GitHub Actions自动生成*"
|
||||
|
||||
# 保存changelog到文件
|
||||
$changelog | Out-File -FilePath "CHANGELOG_${{ steps.calc_version.outputs.new_version }}.md" -Encoding UTF8
|
||||
|
||||
# 输出changelog内容到步骤输出
|
||||
echo "changelog<<EOF" >> $env:GITHUB_OUTPUT
|
||||
echo $changelog >> $env:GITHUB_OUTPUT
|
||||
echo "EOF" >> $env:GITHUB_OUTPUT
|
||||
|
||||
echo "Changelog generated successfully"
|
||||
|
||||
- name: Display version info
|
||||
run: |
|
||||
echo "Current version: ${{ steps.get_version.outputs.current_version }}"
|
||||
echo "New version: ${{ steps.calc_version.outputs.new_version }}"
|
||||
echo "Note: Version will not be automatically updated in repository files"
|
||||
|
||||
- name: Build the Solution
|
||||
run: |
|
||||
msbuild -t:restore /p:GitFlow="Github Action"
|
||||
msbuild /p:platform="AnyCPU" /p:configuration="Release" /p:GitFlow="Github Action" "Ink Canvas/InkCanvasForClass.csproj"
|
||||
|
||||
- name: Create Release Archive
|
||||
run: |
|
||||
$version = "${{ steps.calc_version.outputs.new_version }}"
|
||||
$archiveName = "InkCanvasForClass.CE.$version.0.zip"
|
||||
|
||||
# 创建发布目录
|
||||
New-Item -ItemType Directory -Path "release" -Force
|
||||
|
||||
# 复制发布文件
|
||||
Copy-Item "Ink Canvas\bin\Release\net472\*" "release\" -Recurse -Force
|
||||
|
||||
# 创建压缩包
|
||||
Compress-Archive -Path "release\*" -DestinationPath $archiveName -Force
|
||||
|
||||
echo "archive_name=$archiveName" >> $env:GITHUB_OUTPUT
|
||||
|
||||
- name: Upload Release Assets
|
||||
uses: actions/upload-artifact@v4.5.0
|
||||
with:
|
||||
name: release-files-${{ steps.calc_version.outputs.new_version }}
|
||||
path: |
|
||||
InkCanvasForClass.CE.${{ steps.calc_version.outputs.new_version }}.0.zip
|
||||
CHANGELOG_${{ steps.calc_version.outputs.new_version }}.md
|
||||
|
||||
- name: Prepare Release Info
|
||||
run: |
|
||||
$version = "${{ steps.calc_version.outputs.new_version }}"
|
||||
echo "Preparing release for version: $version"
|
||||
|
||||
- name: Create GitHub Release
|
||||
uses: softprops/action-gh-release@v1
|
||||
with:
|
||||
tag_name: ${{ steps.calc_version.outputs.new_version }}.0
|
||||
name: ICC CE ${{ steps.calc_version.outputs.new_version }}.0
|
||||
body: |
|
||||
${{ steps.changelog.outputs.changelog }}
|
||||
draft: false
|
||||
prerelease: ${{ github.event.inputs.prerelease }}
|
||||
files: |
|
||||
InkCanvasForClass.CE.${{ steps.calc_version.outputs.new_version }}.0.zip
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Generate UpdateLog preview
|
||||
run: |
|
||||
$version = "${{ steps.calc_version.outputs.new_version }}"
|
||||
$changelogFile = "CHANGELOG_$version.md"
|
||||
|
||||
# 读取生成的changelog
|
||||
$changelogContent = Get-Content $changelogFile -Raw
|
||||
|
||||
# 生成预览内容
|
||||
$previewContent = "ICC CE $version.0 更新日志`n" + $changelogContent
|
||||
|
||||
echo "UpdateLog preview generated (not written to file):"
|
||||
echo $previewContent
|
||||
|
||||
- name: Display Summary
|
||||
run: |
|
||||
echo "=== Release Summary ==="
|
||||
echo "Version: ${{ steps.calc_version.outputs.new_version }}"
|
||||
echo "Pre-release: ${{ github.event.inputs.prerelease }}"
|
||||
echo "Changelog: Generated and attached to release"
|
||||
echo "Archive: ICC_CE_${{ steps.calc_version.outputs.new_version }}.zip"
|
||||
echo ""
|
||||
echo "Note: No repository files were modified"
|
||||
echo "You can manually update version numbers and changelog as needed"
|
||||
@@ -1,4 +1,428 @@
|
||||
obj/
|
||||
bin/
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
##
|
||||
## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore
|
||||
|
||||
# User-specific files
|
||||
*.rsuser
|
||||
*.suo
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
*.env
|
||||
|
||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||
*.userprefs
|
||||
|
||||
# Mono auto generated files
|
||||
mono_crash.*
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
[Rr]elease/
|
||||
[Rr]eleases/
|
||||
|
||||
[Dd]ebug/x64/
|
||||
[Dd]ebugPublic/x64/
|
||||
[Rr]elease/x64/
|
||||
[Rr]eleases/x64/
|
||||
bin/x64/
|
||||
obj/x64/
|
||||
|
||||
[Dd]ebug/x86/
|
||||
[Dd]ebugPublic/x86/
|
||||
[Rr]elease/x86/
|
||||
[Rr]eleases/x86/
|
||||
bin/x86/
|
||||
obj/x86/
|
||||
|
||||
[Ww][Ii][Nn]32/
|
||||
[Aa][Rr][Mm]/
|
||||
[Aa][Rr][Mm]64/
|
||||
[Aa][Rr][Mm]64[Ee][Cc]/
|
||||
bld/
|
||||
[Oo]bj/
|
||||
[Oo]ut/
|
||||
[Ll]og/
|
||||
[Ll]ogs/
|
||||
|
||||
# Build results on 'Bin' directories
|
||||
**/[Bb]in/*
|
||||
# Uncomment if you have tasks that rely on *.refresh files to move binaries
|
||||
# (https://github.com/github/gitignore/pull/3736)
|
||||
#!**/[Bb]in/*.refresh
|
||||
|
||||
# Visual Studio 2015/2017 cache/options directory
|
||||
.vs/
|
||||
/Ink Canvas/obj
|
||||
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||
#wwwroot/
|
||||
|
||||
# Visual Studio 2017 auto generated files
|
||||
Generated\ Files/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
*.trx
|
||||
|
||||
# NUnit
|
||||
*.VisualState.xml
|
||||
TestResult.xml
|
||||
nunit-*.xml
|
||||
|
||||
# Approval Tests result files
|
||||
*.received.*
|
||||
|
||||
# Build Results of an ATL Project
|
||||
[Dd]ebugPS/
|
||||
[Rr]eleasePS/
|
||||
dlldata.c
|
||||
|
||||
# Benchmark Results
|
||||
BenchmarkDotNet.Artifacts/
|
||||
|
||||
# .NET Core
|
||||
project.lock.json
|
||||
project.fragment.lock.json
|
||||
artifacts/
|
||||
|
||||
# ASP.NET Scaffolding
|
||||
ScaffoldingReadMe.txt
|
||||
|
||||
# StyleCop
|
||||
StyleCopReport.xml
|
||||
|
||||
# Files built by Visual Studio
|
||||
*_i.c
|
||||
*_p.c
|
||||
*_h.h
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.idb
|
||||
*.iobj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.ipdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
# but not Directory.Build.rsp, as it configures directory-level build defaults
|
||||
!Directory.Build.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*_wpftmp.csproj
|
||||
*.log
|
||||
*.tlog
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
*.pidb
|
||||
*.svclog
|
||||
*.scc
|
||||
|
||||
# Chutzpah Test files
|
||||
_Chutzpah*
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opendb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
*.VC.db
|
||||
*.VC.VC.opendb
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
*.sap
|
||||
|
||||
# Visual Studio Trace Files
|
||||
*.e2e
|
||||
|
||||
# TFS 2012 Local Workspace
|
||||
$tf/
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*/
|
||||
*.[Rr]e[Ss]harper
|
||||
*.DotSettings.user
|
||||
|
||||
# TeamCity is a build add-in
|
||||
_TeamCity*
|
||||
|
||||
# DotCover is a Code Coverage Tool
|
||||
*.dotCover
|
||||
|
||||
# AxoCover is a Code Coverage Tool
|
||||
.axoCover/*
|
||||
!.axoCover/settings.json
|
||||
|
||||
# Coverlet is a free, cross platform Code Coverage Tool
|
||||
coverage*.json
|
||||
coverage*.xml
|
||||
coverage*.info
|
||||
|
||||
# Visual Studio code coverage results
|
||||
*.coverage
|
||||
*.coveragexml
|
||||
|
||||
# NCrunch
|
||||
_NCrunch_*
|
||||
.NCrunch_*
|
||||
.*crunch*.local.xml
|
||||
nCrunchTemp_*
|
||||
|
||||
# MightyMoose
|
||||
*.mm.*
|
||||
AutoTest.Net/
|
||||
|
||||
# Web workbench (sass)
|
||||
.sass-cache/
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress/
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish/
|
||||
|
||||
# Publish Web Output
|
||||
*.[Pp]ublish.xml
|
||||
*.azurePubxml
|
||||
# Note: Comment the next line if you want to checkin your web deploy settings,
|
||||
# but database connection strings (with potential passwords) will be unencrypted
|
||||
*.pubxml
|
||||
*.publishproj
|
||||
|
||||
# Microsoft Azure Web App publish settings. Comment the next line if you want to
|
||||
# checkin your Azure Web App publish settings, but sensitive information contained
|
||||
# in these scripts will be unencrypted
|
||||
PublishScripts/
|
||||
|
||||
# NuGet Packages
|
||||
*.nupkg
|
||||
# NuGet Symbol Packages
|
||||
*.snupkg
|
||||
# The packages folder can be ignored because of Package Restore
|
||||
**/[Pp]ackages/*
|
||||
# except build/, which is used as an MSBuild target.
|
||||
!**/[Pp]ackages/build/
|
||||
# Uncomment if necessary however generally it will be regenerated when needed
|
||||
#!**/[Pp]ackages/repositories.config
|
||||
# NuGet v3's project.json files produces more ignorable files
|
||||
*.nuget.props
|
||||
*.nuget.targets
|
||||
|
||||
# Microsoft Azure Build Output
|
||||
csx/
|
||||
*.build.csdef
|
||||
|
||||
# Microsoft Azure Emulator
|
||||
ecf/
|
||||
rcf/
|
||||
|
||||
# Windows Store app package directories and files
|
||||
AppPackages/
|
||||
BundleArtifacts/
|
||||
Package.StoreAssociation.xml
|
||||
_pkginfo.txt
|
||||
*.appx
|
||||
*.appxbundle
|
||||
*.appxupload
|
||||
|
||||
# Visual Studio cache files
|
||||
# files ending in .cache can be ignored
|
||||
*.[Cc]ache
|
||||
# but keep track of directories ending in .cache
|
||||
!?*.[Cc]ache/
|
||||
|
||||
# Others
|
||||
ClientBin/
|
||||
~$*
|
||||
*~
|
||||
*.dbmdl
|
||||
*.dbproj.schemaview
|
||||
*.jfm
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
orleans.codegen.cs
|
||||
|
||||
# Including strong name files can present a security risk
|
||||
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
|
||||
#*.snk
|
||||
|
||||
# Since there are multiple workflows, uncomment next line to ignore bower_components
|
||||
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
||||
#bower_components/
|
||||
|
||||
# RIA/Silverlight projects
|
||||
Generated_Code/
|
||||
|
||||
# Backup & report files from converting an old project file
|
||||
# to a newer Visual Studio version. Backup files are not needed,
|
||||
# because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
ServiceFabricBackup/
|
||||
*.rptproj.bak
|
||||
|
||||
# SQL Server files
|
||||
*.mdf
|
||||
*.ldf
|
||||
*.ndf
|
||||
|
||||
# Business Intelligence projects
|
||||
*.rdl.data
|
||||
*.bim.layout
|
||||
*.bim_*.settings
|
||||
*.rptproj.rsuser
|
||||
*- [Bb]ackup.rdl
|
||||
*- [Bb]ackup ([0-9]).rdl
|
||||
*- [Bb]ackup ([0-9][0-9]).rdl
|
||||
|
||||
# Microsoft Fakes
|
||||
FakesAssemblies/
|
||||
|
||||
# GhostDoc plugin setting file
|
||||
*.GhostDoc.xml
|
||||
|
||||
# Node.js Tools for Visual Studio
|
||||
.ntvs_analysis.dat
|
||||
node_modules/
|
||||
|
||||
# Visual Studio 6 build log
|
||||
*.plg
|
||||
|
||||
# Visual Studio 6 workspace options file
|
||||
*.opt
|
||||
|
||||
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
|
||||
*.vbw
|
||||
|
||||
# Visual Studio 6 workspace and project file (working project files containing files to include in project)
|
||||
*.dsw
|
||||
*.dsp
|
||||
|
||||
# Visual Studio 6 technical files
|
||||
*.ncb
|
||||
*.aps
|
||||
|
||||
# Visual Studio LightSwitch build output
|
||||
**/*.HTMLClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/ModelManifest.xml
|
||||
**/*.Server/GeneratedArtifacts
|
||||
**/*.Server/ModelManifest.xml
|
||||
_Pvt_Extensions
|
||||
|
||||
# Paket dependency manager
|
||||
**/.paket/paket.exe
|
||||
paket-files/
|
||||
|
||||
# FAKE - F# Make
|
||||
**/.fake/
|
||||
|
||||
# CodeRush personal settings
|
||||
**/.cr/personal
|
||||
|
||||
# Python Tools for Visual Studio (PTVS)
|
||||
**/__pycache__/
|
||||
*.pyc
|
||||
|
||||
# Cake - Uncomment if you are using it
|
||||
#tools/**
|
||||
#!tools/packages.config
|
||||
|
||||
# Tabs Studio
|
||||
*.tss
|
||||
|
||||
# Telerik's JustMock configuration file
|
||||
*.jmconfig
|
||||
|
||||
# BizTalk build output
|
||||
*.btp.cs
|
||||
*.btm.cs
|
||||
*.odx.cs
|
||||
*.xsd.cs
|
||||
|
||||
# OpenCover UI analysis results
|
||||
OpenCover/
|
||||
|
||||
# Azure Stream Analytics local run output
|
||||
ASALocalRun/
|
||||
|
||||
# MSBuild Binary and Structured Log
|
||||
*.binlog
|
||||
MSBuild_Logs/
|
||||
|
||||
# AWS SAM Build and Temporary Artifacts folder
|
||||
.aws-sam
|
||||
|
||||
# NVidia Nsight GPU debugger configuration file
|
||||
*.nvuser
|
||||
|
||||
# MFractors (Xamarin productivity tool) working folder
|
||||
**/.mfractor/
|
||||
|
||||
# Local History for Visual Studio
|
||||
**/.localhistory/
|
||||
|
||||
# Visual Studio History (VSHistory) files
|
||||
.vshistory/
|
||||
|
||||
# BeatPulse healthcheck temp database
|
||||
healthchecksdb
|
||||
|
||||
# Backup folder for Package Reference Convert tool in Visual Studio 2017
|
||||
MigrationBackup/
|
||||
|
||||
# Ionide (cross platform F# VS Code tools) working folder
|
||||
**/.ionide/
|
||||
|
||||
# Fody - auto-generated XML schema
|
||||
FodyWeavers.xsd
|
||||
|
||||
# VS Code files for those working on multiple tools
|
||||
.vscode/*
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/extensions.json
|
||||
!.vscode/*.code-snippets
|
||||
|
||||
# Local History for Visual Studio Code
|
||||
.history/
|
||||
|
||||
# Built Visual Studio Code Extensions
|
||||
*.vsix
|
||||
|
||||
# Windows Installer files from build outputs
|
||||
*.cab
|
||||
*.msi
|
||||
*.msix
|
||||
*.msm
|
||||
*.msp
|
||||
@@ -1 +1 @@
|
||||
1.7.12.0
|
||||
1.7.17.0
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||
<s:String x:Key="/Default/CodeInspection/PencilsConfiguration/ActualSeverity/@EntryValue">WARNING</s:String>
|
||||
<s:String x:Key="/Default/Environment/Hierarchy/Build/BuildTool/CustomBuildToolPath/@EntryValue">C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\Bin\amd64\MSBuild.exe</s:String>
|
||||
<s:Int64 x:Key="/Default/Environment/Hierarchy/Build/BuildTool/MsbuildVersion/@EntryValue">1114112</s:Int64>
|
||||
<s:Boolean x:Key="/Default/ResxEditorPersonal/CheckedGroups/=InkCanvasForClass_002FProperties_002FResources/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/ResxEditorPersonal/Initialized/@EntryValue">True</s:Boolean></wpf:ResourceDictionary>
|
||||
@@ -232,7 +232,7 @@
|
||||
ContextMenu="{StaticResource SysTrayMenu}"
|
||||
IconSource="/Resources/icc.ico"/>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ui:ThemeResources RequestedTheme="Light"/>
|
||||
<ui:ThemeResources/>
|
||||
<ui:XamlControlsResources />
|
||||
<ResourceDictionary Source="Resources/SeewoImageDictionary.xaml"/>
|
||||
<ResourceDictionary Source="Resources/DrawShapeImageDictionary.xaml"/>
|
||||
|
||||
@@ -1,19 +1,15 @@
|
||||
using Hardcodet.Wpf.TaskbarNotification;
|
||||
using Ink_Canvas.Helpers;
|
||||
using Ink_Canvas.Windows;
|
||||
using iNKORE.UI.WPF.Modern.Controls;
|
||||
using Microsoft.Win32;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
@@ -36,15 +32,17 @@ namespace Ink_Canvas
|
||||
|
||||
public static string[] StartArgs;
|
||||
public static string RootPath = Environment.GetEnvironmentVariable("APPDATA") + "\\Ink Canvas\\";
|
||||
|
||||
|
||||
// 新增:标记是否通过--board参数启动
|
||||
public static bool StartWithBoardMode = false;
|
||||
// 新增:标记是否通过--show参数启动
|
||||
public static bool StartWithShowMode = false;
|
||||
// 新增:保存看门狗进程对象
|
||||
private static Process watchdogProcess;
|
||||
public static Process watchdogProcess;
|
||||
// 新增:标记是否为软件内主动退出
|
||||
public static bool IsAppExitByUser;
|
||||
// 新增:标记是否启用了UIA置顶功能
|
||||
public static bool IsUIAccessTopMostEnabled;
|
||||
// 新增:退出信号文件路径
|
||||
private static string watchdogExitSignalFile = Path.Combine(Path.GetTempPath(), "icc_watchdog_exit_" + Process.GetCurrentProcess().Id + ".flag");
|
||||
// 新增:崩溃日志文件路径
|
||||
@@ -302,7 +300,7 @@ namespace Ink_Canvas
|
||||
{
|
||||
string reason = e.Reason == SessionEndReasons.Logoff ? "用户注销" : "系统关机";
|
||||
WriteCrashLog($"系统会话即将结束: {reason}");
|
||||
|
||||
|
||||
// 清理PowerPoint进程守护和悬浮窗拦截器
|
||||
try
|
||||
{
|
||||
@@ -311,13 +309,13 @@ namespace Ink_Canvas
|
||||
if (mainWindow != null)
|
||||
{
|
||||
// 清理PowerPoint进程守护
|
||||
var method = mainWindow.GetType().GetMethod("StopPowerPointProcessMonitoring",
|
||||
var method = mainWindow.GetType().GetMethod("StopPowerPointProcessMonitoring",
|
||||
BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
method?.Invoke(mainWindow, null);
|
||||
WriteCrashLog("PowerPoint进程守护已在系统关机时清理");
|
||||
|
||||
|
||||
// 清理悬浮窗拦截器
|
||||
var interceptorField = mainWindow.GetType().GetField("_floatingWindowInterceptorManager",
|
||||
var interceptorField = mainWindow.GetType().GetField("_floatingWindowInterceptorManager",
|
||||
BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
var interceptorManager = interceptorField?.GetValue(mainWindow);
|
||||
if (interceptorManager != null)
|
||||
@@ -331,7 +329,7 @@ namespace Ink_Canvas
|
||||
{
|
||||
WriteCrashLog($"清理资源失败: {ex.Message}");
|
||||
}
|
||||
|
||||
|
||||
DeviceIdentifier.SaveUsageStatsOnShutdown();
|
||||
}
|
||||
|
||||
@@ -409,12 +407,12 @@ namespace Ink_Canvas
|
||||
|
||||
public static void ShowSplashScreen()
|
||||
{
|
||||
if (_isSplashScreenShown)
|
||||
if (_isSplashScreenShown)
|
||||
{
|
||||
LogHelper.WriteLogToFile("启动画面已经显示,跳过重复显示");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
LogHelper.WriteLogToFile("开始创建启动画面...");
|
||||
@@ -435,12 +433,11 @@ namespace Ink_Canvas
|
||||
public static void CloseSplashScreen()
|
||||
{
|
||||
if (!_isSplashScreenShown || _splashScreen == null) return;
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
_splashScreen.CloseSplashScreen();
|
||||
_isSplashScreenShown = false;
|
||||
LogHelper.WriteLogToFile("启动画面已关闭");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -481,7 +478,7 @@ namespace Ink_Canvas
|
||||
return (bool)obj["appearance"]["enableSplashScreen"];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 如果设置文件不存在或没有该设置,返回默认值false
|
||||
return false;
|
||||
}
|
||||
@@ -596,8 +593,8 @@ namespace Ink_Canvas
|
||||
ShowSplashScreen();
|
||||
SetSplashMessage("正在启动 Ink Canvas...");
|
||||
SetSplashProgress(20);
|
||||
await Task.Delay(500);
|
||||
|
||||
await Task.Delay(500);
|
||||
|
||||
// 强制刷新UI,确保启动画面显示
|
||||
Application.Current.Dispatcher.Invoke(() => { }, DispatcherPriority.Render);
|
||||
}
|
||||
@@ -610,7 +607,7 @@ namespace Ink_Canvas
|
||||
// 检查是否为最终应用启动(更新后的应用)
|
||||
bool isFinalApp = e.Args.Contains("--final-app");
|
||||
bool skipMutexCheck = e.Args.Contains("--skip-mutex-check");
|
||||
|
||||
|
||||
// 检查是否通过--board参数启动
|
||||
bool hasBoardArg = e.Args.Contains("--board");
|
||||
if (hasBoardArg)
|
||||
@@ -633,13 +630,13 @@ namespace Ink_Canvas
|
||||
LogHelper.WriteLogToFile("App | 检测到最终应用启动(更新后的应用)");
|
||||
}
|
||||
|
||||
// 在应用启动时自动释放IACore相关DLL
|
||||
// 释放IACore相关DLL
|
||||
if (_isSplashScreenShown)
|
||||
{
|
||||
SetSplashMessage("正在初始化组件...");
|
||||
SetSplashProgress(40);
|
||||
await Task.Delay(500);
|
||||
}
|
||||
await Task.Delay(500);
|
||||
}
|
||||
try
|
||||
{
|
||||
IACoreDllExtractor.ExtractIACoreDlls();
|
||||
@@ -649,13 +646,29 @@ namespace Ink_Canvas
|
||||
LogHelper.WriteLogToFile($"释放IACore DLL时出错: {ex.Message}", LogHelper.LogType.Error);
|
||||
}
|
||||
|
||||
// 释放UIAccess DLL
|
||||
if (_isSplashScreenShown)
|
||||
{
|
||||
SetSplashMessage("正在初始化组件...");
|
||||
SetSplashProgress(50);
|
||||
await Task.Delay(300);
|
||||
}
|
||||
try
|
||||
{
|
||||
UIAccessDllExtractor.ExtractUIAccessDlls();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogHelper.WriteLogToFile($"释放UIAccess DLL时出错: {ex.Message}", LogHelper.LogType.Error);
|
||||
}
|
||||
|
||||
// 记录应用启动(设备标识符)
|
||||
if (_isSplashScreenShown)
|
||||
{
|
||||
SetSplashMessage("正在加载配置...");
|
||||
SetSplashProgress(60);
|
||||
await Task.Delay(500);
|
||||
}
|
||||
await Task.Delay(500);
|
||||
}
|
||||
DeviceIdentifier.RecordAppLaunch();
|
||||
LogHelper.WriteLogToFile($"App | 设备ID: {DeviceIdentifier.GetDeviceId()}");
|
||||
LogHelper.WriteLogToFile($"App | 使用频率: {DeviceIdentifier.GetUsageFrequency()}");
|
||||
@@ -902,26 +915,34 @@ namespace Ink_Canvas
|
||||
{
|
||||
SetSplashMessage("正在初始化主界面...");
|
||||
SetSplashProgress(80);
|
||||
await Task.Delay(500);
|
||||
}
|
||||
await Task.Delay(500);
|
||||
}
|
||||
var mainWindow = new MainWindow();
|
||||
MainWindow = mainWindow;
|
||||
|
||||
|
||||
// 主窗口加载完成后关闭启动画面
|
||||
mainWindow.Loaded += (s, args) =>
|
||||
{
|
||||
if (_isSplashScreenShown)
|
||||
{
|
||||
SetSplashMessage("启动完成!");
|
||||
SetSplashProgress(100);
|
||||
// 延迟关闭启动画面,让用户看到完成消息
|
||||
Task.Delay(500).ContinueWith(_ =>
|
||||
SetSplashMessage("完成初始化...");
|
||||
SetSplashProgress(80);
|
||||
Task.Delay(300).ContinueWith(_ =>
|
||||
{
|
||||
Dispatcher.Invoke(() => CloseSplashScreen());
|
||||
Dispatcher.Invoke(() =>
|
||||
{
|
||||
SetSplashMessage("启动完成!");
|
||||
SetSplashProgress(100);
|
||||
// 延迟关闭启动画面,让用户看到完成消息
|
||||
Task.Delay(500).ContinueWith(__ =>
|
||||
{
|
||||
Dispatcher.Invoke(() => CloseSplashScreen());
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
mainWindow.Show();
|
||||
|
||||
// 注册.icstk文件关联
|
||||
@@ -1012,7 +1033,7 @@ namespace Ink_Canvas
|
||||
}
|
||||
|
||||
// 看门狗进程
|
||||
private void StartWatchdogIfNeeded()
|
||||
public static void StartWatchdogIfNeeded()
|
||||
{
|
||||
// 避免递归启动
|
||||
if (Environment.GetCommandLineArgs().Contains("--watchdog")) return;
|
||||
@@ -1051,7 +1072,13 @@ namespace Ink_Canvas
|
||||
Thread.Sleep(2000);
|
||||
}
|
||||
// 主进程异常退出,自动重启前判断崩溃后操作
|
||||
SyncCrashActionFromSettings(); // 新增:同步设置
|
||||
SyncCrashActionFromSettings(); // 同步设置
|
||||
|
||||
if (IsUIAccessTopMostEnabled)
|
||||
{
|
||||
Environment.Exit(0);
|
||||
}
|
||||
|
||||
if (CrashAction == CrashActionType.SilentRestart)
|
||||
{
|
||||
StartupCount.Increment();
|
||||
@@ -1064,7 +1091,6 @@ namespace Ink_Canvas
|
||||
string exePath = Process.GetCurrentProcess().MainModule.FileName;
|
||||
Process.Start(exePath);
|
||||
}
|
||||
// CrashActionType.NoAction 时不重启,直接退出
|
||||
}
|
||||
catch { }
|
||||
Environment.Exit(0);
|
||||
|
||||
@@ -10,7 +10,7 @@ using System.Windows;
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("CJK_mkp")]
|
||||
[assembly: AssemblyProduct("InkCanvasForClass")]
|
||||
[assembly: AssemblyCopyright("Copyright © HARKOTEK Studio 2024")]
|
||||
[assembly: AssemblyCopyright("Copyright © CJK_mkp 2025")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
@@ -49,5 +49,5 @@ using System.Windows;
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.7.12.0")]
|
||||
[assembly: AssemblyFileVersion("1.7.12.0")]
|
||||
[assembly: AssemblyVersion("1.7.17.0")]
|
||||
[assembly: AssemblyFileVersion("1.7.17.0")]
|
||||
|
||||
@@ -1,176 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||||
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. -->
|
||||
<xs:element name="Weavers">
|
||||
<xs:complexType>
|
||||
<xs:all>
|
||||
<xs:element name="Costura" minOccurs="0" maxOccurs="1">
|
||||
<xs:complexType>
|
||||
<xs:all>
|
||||
<xs:element minOccurs="0" maxOccurs="1" name="ExcludeAssemblies" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with line breaks</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element minOccurs="0" maxOccurs="1" name="IncludeAssemblies" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>A list of assembly names to include from the default action of "embed all Copy Local references", delimited with line breaks.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element minOccurs="0" maxOccurs="1" name="ExcludeRuntimeAssemblies" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>A list of runtime assembly names to exclude from the default action of "embed all Copy Local references", delimited with line breaks</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element minOccurs="0" maxOccurs="1" name="IncludeRuntimeAssemblies" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>A list of runtime assembly names to include from the default action of "embed all Copy Local references", delimited with line breaks.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element minOccurs="0" maxOccurs="1" name="Unmanaged32Assemblies" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Obsolete, use UnmanagedWinX86Assemblies instead</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element minOccurs="0" maxOccurs="1" name="UnmanagedWinX86Assemblies" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>A list of unmanaged X86 (32 bit) assembly names to include, delimited with line breaks.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element minOccurs="0" maxOccurs="1" name="Unmanaged64Assemblies" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Obsolete, use UnmanagedWinX64Assemblies instead.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element minOccurs="0" maxOccurs="1" name="UnmanagedWinX64Assemblies" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>A list of unmanaged X64 (64 bit) assembly names to include, delimited with line breaks.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element minOccurs="0" maxOccurs="1" name="UnmanagedWinArm64Assemblies" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>A list of unmanaged Arm64 (64 bit) assembly names to include, delimited with line breaks.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element minOccurs="0" maxOccurs="1" name="PreloadOrder" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>The order of preloaded assemblies, delimited with line breaks.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
</xs:all>
|
||||
<xs:attribute name="CreateTemporaryAssemblies" type="xs:boolean">
|
||||
<xs:annotation>
|
||||
<xs:documentation>This will copy embedded files to disk before loading them into memory. This is helpful for some scenarios that expected an assembly to be loaded from a physical file.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="IncludeDebugSymbols" type="xs:boolean">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Controls if .pdbs for reference assemblies are also embedded.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="IncludeRuntimeReferences" type="xs:boolean">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Controls if runtime assemblies are also embedded.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="UseRuntimeReferencePaths" type="xs:boolean">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Controls whether the runtime assemblies are embedded with their full path or only with their assembly name.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="DisableCompression" type="xs:boolean">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Embedded assemblies are compressed by default, and uncompressed when they are loaded. You can turn compression off with this option.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="DisableCleanup" type="xs:boolean">
|
||||
<xs:annotation>
|
||||
<xs:documentation>As part of Costura, embedded assemblies are no longer included as part of the build. This cleanup can be turned off.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="DisableEventSubscription" type="xs:boolean">
|
||||
<xs:annotation>
|
||||
<xs:documentation>The attach method no longer subscribes to the `AppDomain.AssemblyResolve` (.NET 4.x) and `AssemblyLoadContext.Resolving` (.NET 6.0+) events.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="LoadAtModuleInit" type="xs:boolean">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Costura by default will load as part of the module initialization. This flag disables that behavior. Make sure you call CosturaUtility.Initialize() somewhere in your code.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="IgnoreSatelliteAssemblies" type="xs:boolean">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Costura will by default use assemblies with a name like 'resources.dll' as a satellite resource and prepend the output path. This flag disables that behavior.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="ExcludeAssemblies" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with |</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="IncludeAssemblies" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>A list of assembly names to include from the default action of "embed all Copy Local references", delimited with |.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="ExcludeRuntimeAssemblies" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>A list of runtime assembly names to exclude from the default action of "embed all Copy Local references", delimited with |</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="IncludeRuntimeAssemblies" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>A list of runtime assembly names to include from the default action of "embed all Copy Local references", delimited with |.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="Unmanaged32Assemblies" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Obsolete, use UnmanagedWinX86Assemblies instead</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="UnmanagedWinX86Assemblies" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>A list of unmanaged X86 (32 bit) assembly names to include, delimited with |.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="Unmanaged64Assemblies" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Obsolete, use UnmanagedWinX64Assemblies instead</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="UnmanagedWinX64Assemblies" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>A list of unmanaged X64 (64 bit) assembly names to include, delimited with |.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="UnmanagedWinArm64Assemblies" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>A list of unmanaged Arm64 (64 bit) assembly names to include, delimited with |.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="PreloadOrder" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>The order of preloaded assemblies, delimited with |.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:all>
|
||||
<xs:attribute name="VerifyAssembly" type="xs:boolean">
|
||||
<xs:annotation>
|
||||
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="VerifyIgnoreCodes" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="GenerateXsd" type="xs:boolean">
|
||||
<xs:annotation>
|
||||
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:schema>
|
||||
@@ -732,9 +732,9 @@ namespace Ink_Canvas.Helpers
|
||||
/// </summary>
|
||||
public class AdvancedBezierSmoothing
|
||||
{
|
||||
public double SmoothingStrength { get; set; } = 0.6;
|
||||
public double ResampleInterval { get; set; } = 2.0;
|
||||
public int InterpolationSteps { get; set; } = 12;
|
||||
public double SmoothingStrength { get; set; } = 0.6;
|
||||
public double ResampleInterval { get; set; } = 2.0;
|
||||
public int InterpolationSteps { get; set; } = 12;
|
||||
|
||||
public Stroke SmoothStroke(Stroke stroke)
|
||||
{
|
||||
@@ -764,7 +764,7 @@ namespace Ink_Canvas.Helpers
|
||||
{
|
||||
DrawingAttributes = stroke.DrawingAttributes.Clone()
|
||||
};
|
||||
|
||||
|
||||
System.Diagnostics.Debug.WriteLine($"AdvancedBezierSmoothing: 创建平滑笔画成功");
|
||||
return smoothedStroke;
|
||||
}
|
||||
@@ -797,7 +797,7 @@ namespace Ink_Canvas.Helpers
|
||||
|
||||
// 只生成2-3个插值点
|
||||
int steps = 2;
|
||||
|
||||
|
||||
// 生成贝塞尔曲线点
|
||||
for (int j = 1; j <= steps; j++)
|
||||
{
|
||||
@@ -808,7 +808,7 @@ namespace Ink_Canvas.Helpers
|
||||
}
|
||||
|
||||
result.Add(points[points.Length - 1]);
|
||||
|
||||
|
||||
// 去重处理
|
||||
return RemoveDuplicatePoints(result.ToArray());
|
||||
}
|
||||
@@ -827,10 +827,10 @@ namespace Ink_Canvas.Helpers
|
||||
{
|
||||
var lastPoint = result[result.Count - 1];
|
||||
var currentPoint = points[i];
|
||||
|
||||
double distance = Math.Sqrt(Math.Pow(currentPoint.X - lastPoint.X, 2) +
|
||||
|
||||
double distance = Math.Sqrt(Math.Pow(currentPoint.X - lastPoint.X, 2) +
|
||||
Math.Pow(currentPoint.Y - lastPoint.Y, 2));
|
||||
|
||||
|
||||
if (distance > minDistance)
|
||||
{
|
||||
result.Add(currentPoint);
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
using Ink_Canvas.Helpers;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
@@ -213,20 +213,20 @@ namespace Ink_Canvas.Helpers
|
||||
.Select(x => x.group)
|
||||
.ToList();
|
||||
|
||||
// 将"智教联盟"线路组插入到最前面(如果存在)
|
||||
var zhiJiaoGroup = groups.FirstOrDefault(g => g.GroupName == "智教联盟");
|
||||
if (zhiJiaoGroup != null)
|
||||
{
|
||||
orderedGroups.Insert(0, zhiJiaoGroup);
|
||||
LogHelper.WriteLogToFile("AutoUpdate | 智教联盟线路组已插入到首位");
|
||||
}
|
||||
|
||||
// 将"inkeys"线路组插入到第二位(如果存在)
|
||||
// 将"inkeys"线路组插入到最前面(如果存在)
|
||||
var inkeysGroup = groups.FirstOrDefault(g => g.GroupName == "inkeys");
|
||||
if (inkeysGroup != null)
|
||||
{
|
||||
orderedGroups.Insert(1, inkeysGroup);
|
||||
LogHelper.WriteLogToFile("AutoUpdate | inkeys线路组已插入到第二位");
|
||||
orderedGroups.Insert(0, inkeysGroup);
|
||||
LogHelper.WriteLogToFile("AutoUpdate | inkeys线路组已插入到首位");
|
||||
}
|
||||
|
||||
// 将"智教联盟"线路组插入到第二位(如果存在)
|
||||
var zhiJiaoGroup = groups.FirstOrDefault(g => g.GroupName == "智教联盟");
|
||||
if (zhiJiaoGroup != null)
|
||||
{
|
||||
orderedGroups.Insert(1, zhiJiaoGroup);
|
||||
LogHelper.WriteLogToFile("AutoUpdate | 智教联盟线路组已插入到第二位");
|
||||
}
|
||||
|
||||
if (orderedGroups.Count > 0)
|
||||
@@ -671,22 +671,22 @@ namespace Ink_Canvas.Helpers
|
||||
|
||||
SaveDownloadStatus(false);
|
||||
|
||||
// 优先尝试“智教联盟”线路组
|
||||
// 优先尝试"inkeys"线路组和"智教联盟"线路组
|
||||
var zhiJiaoGroup = groups.FirstOrDefault(g => g.GroupName == "智教联盟");
|
||||
var inkeysGroup = groups.FirstOrDefault(g => g.GroupName == "inkeys");
|
||||
if (zhiJiaoGroup != null || inkeysGroup != null)
|
||||
if (inkeysGroup != null || zhiJiaoGroup != null)
|
||||
{
|
||||
var priorityGroups = new List<UpdateLineGroup>();
|
||||
if (zhiJiaoGroup != null)
|
||||
{
|
||||
priorityGroups.Add(zhiJiaoGroup);
|
||||
LogHelper.WriteLogToFile("AutoUpdate | 下载时优先尝试智教联盟线路组");
|
||||
}
|
||||
if (inkeysGroup != null)
|
||||
{
|
||||
priorityGroups.Add(inkeysGroup);
|
||||
LogHelper.WriteLogToFile("AutoUpdate | 下载时优先尝试inkeys线路组");
|
||||
}
|
||||
if (zhiJiaoGroup != null)
|
||||
{
|
||||
priorityGroups.Add(zhiJiaoGroup);
|
||||
LogHelper.WriteLogToFile("AutoUpdate | 下载时优先尝试智教联盟线路组");
|
||||
}
|
||||
groups = priorityGroups.Concat(groups.Where(g => g.GroupName != "智教联盟" && g.GroupName != "inkeys")).ToList();
|
||||
}
|
||||
|
||||
|
||||
@@ -31,22 +31,22 @@ namespace Ink_Canvas.Helpers
|
||||
public FilterInfo CurrentCamera { get; private set; }
|
||||
|
||||
// 新增属性
|
||||
public int RotationAngle
|
||||
{
|
||||
get => _rotationAngle;
|
||||
set => _rotationAngle = Math.Max(0, Math.Min(3, value));
|
||||
public int RotationAngle
|
||||
{
|
||||
get => _rotationAngle;
|
||||
set => _rotationAngle = Math.Max(0, Math.Min(3, value));
|
||||
}
|
||||
|
||||
public int ResolutionWidth
|
||||
{
|
||||
get => _resolutionWidth;
|
||||
set => _resolutionWidth = Math.Max(320, Math.Min(1920, value));
|
||||
|
||||
public int ResolutionWidth
|
||||
{
|
||||
get => _resolutionWidth;
|
||||
set => _resolutionWidth = Math.Max(320, Math.Min(1920, value));
|
||||
}
|
||||
|
||||
public int ResolutionHeight
|
||||
{
|
||||
get => _resolutionHeight;
|
||||
set => _resolutionHeight = Math.Max(240, Math.Min(1080, value));
|
||||
|
||||
public int ResolutionHeight
|
||||
{
|
||||
get => _resolutionHeight;
|
||||
set => _resolutionHeight = Math.Max(240, Math.Min(1080, value));
|
||||
}
|
||||
|
||||
public CameraService()
|
||||
@@ -75,7 +75,7 @@ namespace Ink_Canvas.Helpers
|
||||
{
|
||||
AvailableCameras.Clear();
|
||||
var videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);
|
||||
|
||||
|
||||
foreach (FilterInfo device in videoDevices)
|
||||
{
|
||||
AvailableCameras.Add(device);
|
||||
@@ -265,27 +265,27 @@ namespace Ink_Canvas.Helpers
|
||||
{
|
||||
// 释放之前的帧
|
||||
_currentFrame?.Dispose();
|
||||
|
||||
|
||||
// 创建新的位图,避免Clone的问题
|
||||
var sourceFrame = eventArgs.Frame;
|
||||
|
||||
|
||||
if (sourceFrame != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
var width = sourceFrame.Width;
|
||||
var height = sourceFrame.Height;
|
||||
|
||||
if (width > 0 && height > 0)
|
||||
{
|
||||
// 应用旋转
|
||||
Bitmap rotatedFrame = ApplyRotation(sourceFrame);
|
||||
|
||||
// 应用分辨率调整
|
||||
_currentFrame = ResizeImage(rotatedFrame, _resolutionWidth, _resolutionHeight);
|
||||
|
||||
rotatedFrame?.Dispose();
|
||||
}
|
||||
|
||||
if (width > 0 && height > 0)
|
||||
{
|
||||
// 应用旋转
|
||||
Bitmap rotatedFrame = ApplyRotation(sourceFrame);
|
||||
|
||||
// 应用分辨率调整
|
||||
_currentFrame = ResizeImage(rotatedFrame, _resolutionWidth, _resolutionHeight);
|
||||
|
||||
rotatedFrame?.Dispose();
|
||||
}
|
||||
else
|
||||
{
|
||||
_currentFrame = null;
|
||||
@@ -379,7 +379,7 @@ namespace Ink_Canvas.Helpers
|
||||
public void Dispose()
|
||||
{
|
||||
StopPreview();
|
||||
|
||||
|
||||
lock (_frameLock)
|
||||
{
|
||||
_currentFrame?.Dispose();
|
||||
|
||||
@@ -112,4 +112,27 @@ namespace Ink_Canvas.Converter
|
||||
}
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotImplementedException(); }
|
||||
}
|
||||
|
||||
public class InverseBooleanToVisibilityConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
if ((bool)value)
|
||||
{
|
||||
return Visibility.Collapsed;
|
||||
}
|
||||
|
||||
return Visibility.Visible;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
if ((bool)value)
|
||||
{
|
||||
return Visibility.Collapsed;
|
||||
}
|
||||
|
||||
return Visibility.Visible;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -419,7 +419,7 @@ namespace Ink_Canvas.Helpers
|
||||
try
|
||||
{
|
||||
string tempDir = Path.GetTempPath();
|
||||
|
||||
|
||||
// 处理文件路径IPC文件
|
||||
string[] ipcFiles = Directory.GetFiles(tempDir, IpcFilePrefix + "*.tmp");
|
||||
foreach (string ipcFile in ipcFiles)
|
||||
|
||||
@@ -242,7 +242,7 @@ namespace Ink_Canvas.Helpers
|
||||
public string Description { get; set; }
|
||||
public InterceptType? ParentType { get; set; }
|
||||
public List<InterceptType> ChildTypes { get; set; } = new List<InterceptType>();
|
||||
|
||||
|
||||
// 新增的精确匹配字段
|
||||
public bool HasWindowStyle { get; set; }
|
||||
public uint WindowStyle { get; set; }
|
||||
@@ -251,7 +251,7 @@ namespace Ink_Canvas.Helpers
|
||||
public int WindowHeight { get; set; }
|
||||
public bool ExactTitleMatch { get; set; } = false;
|
||||
public bool ExactClassNameMatch { get; set; } = false;
|
||||
|
||||
|
||||
// 运行时状态字段
|
||||
public bool foundHwnd { get; set; } = false;
|
||||
public IntPtr outHwnd { get; set; } = IntPtr.Zero;
|
||||
@@ -267,7 +267,7 @@ namespace Ink_Canvas.Helpers
|
||||
private readonly Dispatcher _dispatcher;
|
||||
private bool _isRunning;
|
||||
private bool _disposed;
|
||||
|
||||
|
||||
// 简化的性能统计
|
||||
private int _consecutiveEmptyScans = 0;
|
||||
private DateTime _lastSuccessfulScan = DateTime.Now;
|
||||
@@ -466,15 +466,15 @@ namespace Ink_Canvas.Helpers
|
||||
RequiresAdmin = true,
|
||||
Description = "畅言智慧课堂 主栏悬浮窗",
|
||||
ParentType = null,
|
||||
ChildTypes = new List<InterceptType>
|
||||
{
|
||||
InterceptType.ChangYanBrushSettings,
|
||||
InterceptType.ChangYanSwipeClear,
|
||||
InterceptType.ChangYanInteraction,
|
||||
InterceptType.ChangYanSubjectApp,
|
||||
InterceptType.ChangYanControl,
|
||||
InterceptType.ChangYanCommonTools,
|
||||
InterceptType.ChangYanSceneToolbar,
|
||||
ChildTypes = new List<InterceptType>
|
||||
{
|
||||
InterceptType.ChangYanBrushSettings,
|
||||
InterceptType.ChangYanSwipeClear,
|
||||
InterceptType.ChangYanInteraction,
|
||||
InterceptType.ChangYanSubjectApp,
|
||||
InterceptType.ChangYanControl,
|
||||
InterceptType.ChangYanCommonTools,
|
||||
InterceptType.ChangYanSceneToolbar,
|
||||
InterceptType.ChangYanDrawWindow
|
||||
}
|
||||
};
|
||||
@@ -713,7 +713,7 @@ namespace Ink_Canvas.Helpers
|
||||
if (_isRunning) return;
|
||||
|
||||
_isRunning = true;
|
||||
_scanTimer.Change(0, Math.Max(scanIntervalMs, 2000));
|
||||
_scanTimer.Change(0, Math.Max(scanIntervalMs, 2000));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -725,7 +725,7 @@ namespace Ink_Canvas.Helpers
|
||||
|
||||
_isRunning = false;
|
||||
_scanTimer.Change(Timeout.Infinite, Timeout.Infinite);
|
||||
|
||||
|
||||
// 恢复所有被拦截的窗口
|
||||
RestoreAllWindows();
|
||||
}
|
||||
@@ -774,9 +774,9 @@ namespace Ink_Canvas.Helpers
|
||||
{
|
||||
var parentRule = _interceptRules[rule.ParentType.Value];
|
||||
// 检查是否还有其他启用的子规则
|
||||
bool hasEnabledChildren = parentRule.ChildTypes.Any(childType =>
|
||||
bool hasEnabledChildren = parentRule.ChildTypes.Any(childType =>
|
||||
_interceptRules.ContainsKey(childType) && _interceptRules[childType].IsEnabled);
|
||||
|
||||
|
||||
// 如果没有启用的子规则,则禁用父规则
|
||||
if (!hasEnabledChildren)
|
||||
{
|
||||
@@ -831,7 +831,7 @@ namespace Ink_Canvas.Helpers
|
||||
{
|
||||
var windowsToRestore = new List<IntPtr>(_interceptedWindows.Keys);
|
||||
var restoredCount = 0;
|
||||
|
||||
|
||||
foreach (var hWnd in windowsToRestore)
|
||||
{
|
||||
if (RestoreWindow(hWnd))
|
||||
@@ -839,7 +839,7 @@ namespace Ink_Canvas.Helpers
|
||||
restoredCount++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -864,7 +864,7 @@ namespace Ink_Canvas.Helpers
|
||||
restoredCount++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -875,22 +875,22 @@ namespace Ink_Canvas.Helpers
|
||||
if (!_interceptedWindows.ContainsKey(hWnd)) return false;
|
||||
|
||||
var interceptType = _interceptedWindows[hWnd];
|
||||
|
||||
|
||||
if (IsWindow(hWnd))
|
||||
{
|
||||
// 使用多种方法确保窗口恢复显示
|
||||
ShowWindow(hWnd, SW_RESTORE);
|
||||
ShowWindow(hWnd, SW_SHOW);
|
||||
ShowWindow(hWnd, SW_SHOWNORMAL);
|
||||
|
||||
|
||||
// 将窗口置于前台并显示
|
||||
SetWindowPos(hWnd, IntPtr.Zero, 0, 0, 0, 0,
|
||||
SetWindowPos(hWnd, IntPtr.Zero, 0, 0, 0, 0,
|
||||
SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW);
|
||||
|
||||
|
||||
// 强制将窗口带到前台
|
||||
BringWindowToTop(hWnd);
|
||||
SetForegroundWindow(hWnd);
|
||||
|
||||
|
||||
_interceptedWindows.Remove(hWnd);
|
||||
|
||||
WindowRestored?.Invoke(this, new WindowRestoredEventArgs
|
||||
@@ -916,7 +916,7 @@ namespace Ink_Canvas.Helpers
|
||||
private void CleanupInvalidWindows()
|
||||
{
|
||||
var invalidWindows = new List<IntPtr>();
|
||||
|
||||
|
||||
foreach (var kvp in _interceptedWindows)
|
||||
{
|
||||
var hWnd = kvp.Key;
|
||||
@@ -940,7 +940,7 @@ namespace Ink_Canvas.Helpers
|
||||
// 简化的扫描逻辑
|
||||
var interceptedCount = 0;
|
||||
CleanupInvalidWindows();
|
||||
|
||||
|
||||
// 重置所有规则的发现状态
|
||||
foreach (var rule in _interceptRules.Values)
|
||||
{
|
||||
@@ -958,9 +958,9 @@ namespace Ink_Canvas.Helpers
|
||||
{
|
||||
if (rule.IsEnabled && rule.foundHwnd && rule.outHwnd != IntPtr.Zero)
|
||||
{
|
||||
bool shouldIntercept = !_interceptedWindows.ContainsKey(rule.outHwnd) ||
|
||||
bool shouldIntercept = !_interceptedWindows.ContainsKey(rule.outHwnd) ||
|
||||
(_interceptedWindows.ContainsKey(rule.outHwnd) && IsWindowVisible(rule.outHwnd));
|
||||
|
||||
|
||||
if (shouldIntercept)
|
||||
{
|
||||
InterceptWindow(rule.outHwnd, rule);
|
||||
@@ -1068,7 +1068,7 @@ namespace Ink_Canvas.Helpers
|
||||
var className = new StringBuilder(256);
|
||||
GetClassName(hWnd, className, className.Capacity);
|
||||
var classNameStr = className.ToString();
|
||||
|
||||
|
||||
if (rule.ExactClassNameMatch)
|
||||
{
|
||||
if (!classNameStr.Equals(rule.ClassNamePattern, StringComparison.OrdinalIgnoreCase))
|
||||
@@ -1087,7 +1087,7 @@ namespace Ink_Canvas.Helpers
|
||||
var windowTitle = new StringBuilder(256);
|
||||
GetWindowText(hWnd, windowTitle, windowTitle.Capacity);
|
||||
var titleStr = windowTitle.ToString();
|
||||
|
||||
|
||||
if (rule.ExactTitleMatch)
|
||||
{
|
||||
if (!titleStr.Equals(rule.WindowTitlePattern, StringComparison.OrdinalIgnoreCase))
|
||||
@@ -1126,7 +1126,7 @@ namespace Ink_Canvas.Helpers
|
||||
var horizontalDPI = GetDeviceCaps(hdc, LOGPIXELSX);
|
||||
var verticalDPI = GetDeviceCaps(hdc, LOGPIXELSY);
|
||||
ReleaseDC(IntPtr.Zero, hdc);
|
||||
|
||||
|
||||
var scale = (horizontalDPI + verticalDPI) / 2.0f / 96.0f;
|
||||
var scaledWidth = (int)(rule.WindowWidth * scale);
|
||||
var scaledHeight = (int)(rule.WindowHeight * scale);
|
||||
@@ -1164,10 +1164,10 @@ namespace Ink_Canvas.Helpers
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// 直接隐藏窗口,不发送关闭消息
|
||||
ShowWindow(hWnd, SW_HIDE);
|
||||
|
||||
|
||||
// 记录拦截的窗口
|
||||
_interceptedWindows[hWnd] = rule.Type;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using Ink_Canvas.Helpers;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Ink_Canvas.Helpers;
|
||||
|
||||
namespace Ink_Canvas
|
||||
{
|
||||
@@ -46,7 +46,7 @@ namespace Ink_Canvas
|
||||
{
|
||||
_settings = settings ?? new FloatingWindowInterceptorSettings();
|
||||
_interceptor = new FloatingWindowInterceptor();
|
||||
|
||||
|
||||
// 订阅事件
|
||||
_interceptor.WindowIntercepted += OnWindowIntercepted;
|
||||
_interceptor.WindowRestored += OnWindowRestored;
|
||||
@@ -116,7 +116,7 @@ namespace Ink_Canvas
|
||||
try
|
||||
{
|
||||
_interceptor.SetInterceptRule(type, enabled);
|
||||
|
||||
|
||||
// 更新设置
|
||||
var ruleName = type.ToString();
|
||||
if (_settings.InterceptRules.ContainsKey(ruleName))
|
||||
@@ -258,7 +258,7 @@ namespace Ink_Canvas
|
||||
try
|
||||
{
|
||||
_settings.ScanIntervalMs = intervalMs;
|
||||
|
||||
|
||||
// 如果正在运行,重启以应用新间隔
|
||||
if (IsRunning)
|
||||
{
|
||||
@@ -6,8 +6,8 @@ using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Forms;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace Ink_Canvas.Helpers
|
||||
{
|
||||
@@ -21,12 +21,12 @@ namespace Ink_Canvas.Helpers
|
||||
private readonly MainWindow _mainWindow;
|
||||
private bool _isDisposed;
|
||||
private bool _hotkeysShouldBeRegistered = true; // 启动时注册热键
|
||||
|
||||
|
||||
// 多屏幕支持相关字段
|
||||
private Screen _currentScreen;
|
||||
private bool _isMultiScreenMode = false;
|
||||
private bool _enableScreenSpecificHotkeys = true; // 是否启用基于屏幕的热键注册
|
||||
|
||||
|
||||
// 智能热键管理相关字段
|
||||
private bool _isWindowFocused = false;
|
||||
private bool _isMouseOverWindow = false;
|
||||
@@ -42,10 +42,10 @@ namespace Ink_Canvas.Helpers
|
||||
_mainWindow = mainWindow ?? throw new ArgumentNullException(nameof(mainWindow));
|
||||
_registeredHotkeys = new Dictionary<string, HotkeyInfo>();
|
||||
_hotkeysShouldBeRegistered = true; // 启动时注册热键
|
||||
|
||||
|
||||
// 初始化多屏幕支持
|
||||
InitializeMultiScreenSupport();
|
||||
|
||||
|
||||
// 启动时确保配置文件存在
|
||||
EnsureConfigFileExists();
|
||||
}
|
||||
@@ -106,10 +106,10 @@ namespace Ink_Canvas.Helpers
|
||||
});
|
||||
|
||||
_registeredHotkeys[hotkeyName] = hotkeyInfo;
|
||||
|
||||
|
||||
// 记录注册信息
|
||||
var screenInfo = _isMultiScreenMode ? $" (屏幕: {_currentScreen?.DeviceName})" : "";
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -506,7 +506,7 @@ namespace Ink_Canvas.Helpers
|
||||
try
|
||||
{
|
||||
_enableScreenSpecificHotkeys = true;
|
||||
|
||||
|
||||
// 如果当前在多屏幕环境下,刷新热键注册
|
||||
if (_isMultiScreenMode)
|
||||
{
|
||||
@@ -527,7 +527,7 @@ namespace Ink_Canvas.Helpers
|
||||
try
|
||||
{
|
||||
_enableScreenSpecificHotkeys = false;
|
||||
|
||||
|
||||
// 重新注册热键(全局模式)
|
||||
if (_hotkeysShouldBeRegistered)
|
||||
{
|
||||
@@ -599,15 +599,15 @@ namespace Ink_Canvas.Helpers
|
||||
{
|
||||
// 检测是否有多个屏幕
|
||||
_isMultiScreenMode = ScreenDetectionHelper.HasMultipleScreens();
|
||||
|
||||
|
||||
if (_isMultiScreenMode)
|
||||
{
|
||||
// 获取当前窗口所在的屏幕
|
||||
_currentScreen = ScreenDetectionHelper.GetWindowScreen(_mainWindow);
|
||||
|
||||
|
||||
// 监听窗口位置变化事件
|
||||
_mainWindow.LocationChanged += OnWindowLocationChanged;
|
||||
|
||||
|
||||
// 初始化智能热键管理
|
||||
InitializeSmartHotkeyManagement();
|
||||
}
|
||||
@@ -634,16 +634,16 @@ namespace Ink_Canvas.Helpers
|
||||
// 监听窗口焦点事件
|
||||
_mainWindow.GotFocus += OnWindowGotFocus;
|
||||
_mainWindow.LostFocus += OnWindowLostFocus;
|
||||
|
||||
|
||||
// 监听鼠标进入/离开事件
|
||||
_mainWindow.MouseEnter += OnMouseEnterWindow;
|
||||
_mainWindow.MouseLeave += OnMouseLeaveWindow;
|
||||
|
||||
|
||||
// 初始化鼠标位置监控定时器
|
||||
_mousePositionTimer = new System.Windows.Threading.DispatcherTimer();
|
||||
_mousePositionTimer.Interval = TimeSpan.FromMilliseconds(500); // 每500ms检查一次
|
||||
_mousePositionTimer.Tick += OnMousePositionTimerTick;
|
||||
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -665,7 +665,7 @@ namespace Ink_Canvas.Helpers
|
||||
if (newScreen != null && newScreen != _currentScreen)
|
||||
{
|
||||
_currentScreen = newScreen;
|
||||
|
||||
|
||||
// 重新注册热键以适应新屏幕
|
||||
RefreshHotkeysForCurrentScreen();
|
||||
}
|
||||
@@ -691,7 +691,7 @@ namespace Ink_Canvas.Helpers
|
||||
|
||||
// 重新注册热键
|
||||
LoadHotkeysFromSettings();
|
||||
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -776,12 +776,12 @@ namespace Ink_Canvas.Helpers
|
||||
// 检查鼠标是否在当前窗口所在的屏幕上
|
||||
var mousePosition = Control.MousePosition;
|
||||
var currentScreen = Screen.FromPoint(mousePosition);
|
||||
|
||||
|
||||
// 无论屏幕是否变化,都检查热键状态
|
||||
// 这样可以确保热键状态始终与当前上下文保持一致
|
||||
bool shouldEnableHotkeys = ShouldEnableHotkeysBasedOnContext();
|
||||
bool currentlyHasHotkeys = _registeredHotkeys.Count > 0;
|
||||
|
||||
|
||||
if (shouldEnableHotkeys && !currentlyHasHotkeys)
|
||||
{
|
||||
UpdateHotkeyStateBasedOnContext();
|
||||
@@ -808,27 +808,19 @@ namespace Ink_Canvas.Helpers
|
||||
return;
|
||||
|
||||
bool shouldEnableHotkeys = ShouldEnableHotkeysBasedOnContext();
|
||||
|
||||
if (shouldEnableHotkeys)
|
||||
bool currentlyHasHotkeys = _registeredHotkeys.Count > 0;
|
||||
|
||||
if (shouldEnableHotkeys && !currentlyHasHotkeys)
|
||||
{
|
||||
// 如果热键未注册,则注册
|
||||
if (_registeredHotkeys.Count == 0)
|
||||
{
|
||||
LoadHotkeysFromSettings();
|
||||
}
|
||||
// 需要注册快捷键
|
||||
LoadHotkeysFromSettings();
|
||||
}
|
||||
else
|
||||
else if (!shouldEnableHotkeys && currentlyHasHotkeys)
|
||||
{
|
||||
// 如果热键已注册,则注销(与鼠标模式禁用保持一致)
|
||||
if (_registeredHotkeys.Count > 0)
|
||||
{
|
||||
UnregisterAllHotkeys();
|
||||
|
||||
// 注意:这里不设置 _hotkeysShouldBeRegistered = false
|
||||
// 因为我们需要保持热键系统的启用状态,只是暂时注销热键
|
||||
// 这样当上下文变化时,热键可以重新注册
|
||||
}
|
||||
// 需要注销快捷键
|
||||
UnregisterAllHotkeys();
|
||||
}
|
||||
// 如果状态没有变化,则不进行任何操作
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -871,36 +863,50 @@ namespace Ink_Canvas.Helpers
|
||||
{
|
||||
try
|
||||
{
|
||||
// 策略1:鼠标在窗口上时启用热键(最高优先级)
|
||||
if (_isMouseOverWindow)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
// 检查当前是否处于鼠标模式
|
||||
bool isMouseMode = IsInSelectMode();
|
||||
|
||||
// 策略2:在多屏幕环境下,检查鼠标是否在当前窗口所在的屏幕上
|
||||
if (_isMultiScreenMode)
|
||||
if (isMouseMode)
|
||||
{
|
||||
var mousePosition = Control.MousePosition;
|
||||
var mouseScreen = Screen.FromPoint(mousePosition);
|
||||
|
||||
if (mouseScreen == _currentScreen)
|
||||
// 鼠标模式下,根据设置决定是否启用快捷键
|
||||
return MainWindow.Settings.Appearance.EnableHotkeysInMouseMode;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 非鼠标模式下,需要检查焦点和屏幕位置
|
||||
|
||||
// 策略1:鼠标在窗口上时启用热键(最高优先级)
|
||||
if (_isMouseOverWindow)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 策略3:单屏幕环境下,窗口有焦点时启用热键
|
||||
if (_isWindowFocused)
|
||||
{
|
||||
// 策略2:在多屏幕环境下,检查鼠标是否在当前窗口所在的屏幕上
|
||||
if (_isMultiScreenMode && _enableScreenSpecificHotkeys)
|
||||
{
|
||||
var mousePosition = Control.MousePosition;
|
||||
var mouseScreen = Screen.FromPoint(mousePosition);
|
||||
|
||||
if (mouseScreen == _currentScreen)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 策略3:单屏幕环境下,窗口有焦点时启用热键
|
||||
if (_isWindowFocused)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// 策略4:如果以上都不满足,但在非鼠标模式下,仍然启用快捷键
|
||||
// 这样可以确保在批注模式下快捷键始终可用
|
||||
return true;
|
||||
}
|
||||
|
||||
// 默认情况:禁用热键
|
||||
return false;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -1344,14 +1350,14 @@ namespace Ink_Canvas.Helpers
|
||||
{
|
||||
// 注销所有快捷键
|
||||
UnregisterAllHotkeys();
|
||||
|
||||
|
||||
// 停止定时器
|
||||
if (_mousePositionTimer != null)
|
||||
{
|
||||
_mousePositionTimer.Stop();
|
||||
_mousePositionTimer = null;
|
||||
}
|
||||
|
||||
|
||||
// 移除事件监听器
|
||||
if (_mainWindow != null)
|
||||
{
|
||||
@@ -1359,7 +1365,7 @@ namespace Ink_Canvas.Helpers
|
||||
{
|
||||
_mainWindow.LocationChanged -= OnWindowLocationChanged;
|
||||
}
|
||||
|
||||
|
||||
_mainWindow.GotFocus -= OnWindowGotFocus;
|
||||
_mainWindow.LostFocus -= OnWindowLostFocus;
|
||||
_mainWindow.MouseEnter -= OnMouseEnterWindow;
|
||||
|
||||
@@ -77,40 +77,40 @@ namespace Ink_Canvas.Helpers
|
||||
{
|
||||
// 保存用户设置的异步处理偏好
|
||||
bool userAsyncPreference = UseAsyncProcessing;
|
||||
|
||||
|
||||
switch (Quality)
|
||||
{
|
||||
case SmoothingQuality.Performance:
|
||||
SmoothingStrength = 0.15;
|
||||
ResampleInterval = 5.0;
|
||||
InterpolationSteps = 4;
|
||||
SmoothingStrength = 0.15;
|
||||
ResampleInterval = 5.0;
|
||||
InterpolationSteps = 4;
|
||||
UseAdaptiveInterpolation = false;
|
||||
CurveTension = 0.15;
|
||||
CurveTension = 0.15;
|
||||
MaxConcurrentTasks = Math.Max(1, Environment.ProcessorCount / 2);
|
||||
UseHardwareAcceleration = true;
|
||||
UseAsyncProcessing = userAsyncPreference;
|
||||
UseHardwareAcceleration = true;
|
||||
UseAsyncProcessing = userAsyncPreference;
|
||||
break;
|
||||
|
||||
case SmoothingQuality.Balanced:
|
||||
SmoothingStrength = 0.3;
|
||||
ResampleInterval = 3.0;
|
||||
InterpolationSteps = 8;
|
||||
SmoothingStrength = 0.3;
|
||||
ResampleInterval = 3.0;
|
||||
InterpolationSteps = 8;
|
||||
UseAdaptiveInterpolation = true;
|
||||
CurveTension = 0.25;
|
||||
CurveTension = 0.25;
|
||||
MaxConcurrentTasks = Environment.ProcessorCount;
|
||||
UseHardwareAcceleration = true;
|
||||
UseAsyncProcessing = userAsyncPreference;
|
||||
UseAsyncProcessing = userAsyncPreference;
|
||||
break;
|
||||
|
||||
case SmoothingQuality.Quality:
|
||||
SmoothingStrength = 0.5;
|
||||
ResampleInterval = 2.0;
|
||||
InterpolationSteps = 15;
|
||||
SmoothingStrength = 0.5;
|
||||
ResampleInterval = 2.0;
|
||||
InterpolationSteps = 15;
|
||||
UseAdaptiveInterpolation = true;
|
||||
CurveTension = 0.35;
|
||||
CurveTension = 0.35;
|
||||
MaxConcurrentTasks = Environment.ProcessorCount;
|
||||
UseHardwareAcceleration = true;
|
||||
UseAsyncProcessing = userAsyncPreference;
|
||||
UseAsyncProcessing = userAsyncPreference;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace Ink_Canvas.Helpers
|
||||
private readonly object _lockObject = new object();
|
||||
private bool _disposed;
|
||||
private string _currentActivePresentationId = "";
|
||||
|
||||
|
||||
// 墨迹备份机制
|
||||
private readonly Dictionary<string, Dictionary<int, StrokeCollection>> _strokeBackups;
|
||||
private DateTime _lastBackupTime = DateTime.MinValue;
|
||||
@@ -55,7 +55,7 @@ namespace Ink_Canvas.Helpers
|
||||
try
|
||||
{
|
||||
var presentationId = GeneratePresentationId(presentation);
|
||||
|
||||
|
||||
// 如果已存在该演示文稿的管理器,先清理
|
||||
if (_presentationManagers.ContainsKey(presentationId))
|
||||
{
|
||||
@@ -104,11 +104,11 @@ namespace Ink_Canvas.Helpers
|
||||
try
|
||||
{
|
||||
var presentationId = GeneratePresentationId(presentation);
|
||||
|
||||
|
||||
if (_presentationManagers.ContainsKey(presentationId))
|
||||
{
|
||||
// 如果切换的是不同的演示文稿,先保存当前活跃演示文稿的墨迹
|
||||
if (!string.IsNullOrEmpty(_currentActivePresentationId) &&
|
||||
if (!string.IsNullOrEmpty(_currentActivePresentationId) &&
|
||||
_currentActivePresentationId != presentationId)
|
||||
{
|
||||
var currentManager = GetCurrentManager();
|
||||
@@ -132,7 +132,7 @@ namespace Ink_Canvas.Helpers
|
||||
}
|
||||
|
||||
_currentActivePresentationId = presentationId;
|
||||
|
||||
|
||||
// 更新最后访问时间
|
||||
if (_presentationInfos.ContainsKey(presentationId))
|
||||
{
|
||||
@@ -176,13 +176,13 @@ namespace Ink_Canvas.Helpers
|
||||
{
|
||||
// 保存到管理器
|
||||
manager.SaveCurrentSlideStrokes(slideIndex, strokes);
|
||||
|
||||
|
||||
// 只有在保存成功后才创建备份
|
||||
if (!string.IsNullOrEmpty(_currentActivePresentationId))
|
||||
{
|
||||
CreateStrokeBackup(_currentActivePresentationId, slideIndex, strokes);
|
||||
}
|
||||
|
||||
|
||||
// 检查是否需要执行定期备份
|
||||
CheckAndPerformBackup();
|
||||
}
|
||||
@@ -233,7 +233,7 @@ namespace Ink_Canvas.Helpers
|
||||
if (manager != null)
|
||||
{
|
||||
var strokes = manager.LoadSlideStrokes(slideIndex);
|
||||
|
||||
|
||||
// 如果从管理器加载失败,尝试从备份恢复
|
||||
if (strokes == null || strokes.Count == 0)
|
||||
{
|
||||
@@ -242,14 +242,14 @@ namespace Ink_Canvas.Helpers
|
||||
strokes = RestoreStrokeFromBackup(_currentActivePresentationId, slideIndex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return strokes ?? new StrokeCollection();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogHelper.WriteLogToFile($"加载页面墨迹失败: {ex}", LogHelper.LogType.Error);
|
||||
|
||||
|
||||
// 尝试从备份恢复
|
||||
if (!string.IsNullOrEmpty(_currentActivePresentationId))
|
||||
{
|
||||
@@ -464,12 +464,12 @@ namespace Ink_Canvas.Helpers
|
||||
try
|
||||
{
|
||||
var presentationId = GeneratePresentationId(presentation);
|
||||
|
||||
|
||||
if (_presentationManagers.ContainsKey(presentationId))
|
||||
{
|
||||
// 保存墨迹到文件
|
||||
_presentationManagers[presentationId].SaveAllStrokesToFile(presentation);
|
||||
|
||||
|
||||
// 释放资源
|
||||
_presentationManagers[presentationId].Dispose();
|
||||
_presentationManagers.Remove(presentationId);
|
||||
@@ -550,13 +550,13 @@ namespace Ink_Canvas.Helpers
|
||||
_presentationManagers.Remove(id);
|
||||
}
|
||||
_presentationInfos.Remove(id);
|
||||
|
||||
|
||||
// 清理备份数据
|
||||
if (_strokeBackups.ContainsKey(id))
|
||||
{
|
||||
_strokeBackups.Remove(id);
|
||||
}
|
||||
|
||||
|
||||
LogHelper.WriteLogToFile($"已清理非活跃演示文稿: {id}", LogHelper.LogType.Trace);
|
||||
}
|
||||
}
|
||||
@@ -589,7 +589,7 @@ namespace Ink_Canvas.Helpers
|
||||
|
||||
// 创建新的备份
|
||||
_strokeBackups[presentationId][slideIndex] = strokes.Clone();
|
||||
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -604,7 +604,7 @@ namespace Ink_Canvas.Helpers
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_strokeBackups.ContainsKey(presentationId) &&
|
||||
if (_strokeBackups.ContainsKey(presentationId) &&
|
||||
_strokeBackups[presentationId].ContainsKey(slideIndex))
|
||||
{
|
||||
var backup = _strokeBackups[presentationId][slideIndex];
|
||||
@@ -631,7 +631,7 @@ namespace Ink_Canvas.Helpers
|
||||
try
|
||||
{
|
||||
var now = DateTime.Now;
|
||||
|
||||
|
||||
// 检查是否需要执行备份
|
||||
if (now - _lastBackupTime < TimeSpan.FromMinutes(BackupIntervalMinutes))
|
||||
{
|
||||
@@ -639,7 +639,7 @@ namespace Ink_Canvas.Helpers
|
||||
}
|
||||
|
||||
// 备份当前活跃演示文稿的所有墨迹
|
||||
if (!string.IsNullOrEmpty(_currentActivePresentationId) &&
|
||||
if (!string.IsNullOrEmpty(_currentActivePresentationId) &&
|
||||
_presentationManagers.ContainsKey(_currentActivePresentationId))
|
||||
{
|
||||
var manager = _presentationManagers[_currentActivePresentationId];
|
||||
@@ -661,7 +661,7 @@ namespace Ink_Canvas.Helpers
|
||||
#region Private Methods
|
||||
private PPTInkManager GetCurrentManager()
|
||||
{
|
||||
if (string.IsNullOrEmpty(_currentActivePresentationId) ||
|
||||
if (string.IsNullOrEmpty(_currentActivePresentationId) ||
|
||||
!_presentationManagers.ContainsKey(_currentActivePresentationId))
|
||||
{
|
||||
return null;
|
||||
@@ -780,7 +780,7 @@ namespace Ink_Canvas.Helpers
|
||||
}
|
||||
_presentationManagers.Clear();
|
||||
_presentationInfos.Clear();
|
||||
|
||||
|
||||
// 清理备份数据
|
||||
foreach (var backupDict in _strokeBackups.Values)
|
||||
{
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace Ink_Canvas.Helpers
|
||||
{
|
||||
private bool _needsRedraw = true;
|
||||
private int _lastPointCount = 0;
|
||||
private const int REDRAW_THRESHOLD = 3;
|
||||
private const int REDRAW_THRESHOLD = 3;
|
||||
|
||||
/// <summary>
|
||||
/// 创建显示笔迹的类
|
||||
@@ -53,7 +53,7 @@ namespace Ink_Canvas.Helpers
|
||||
public StrokeVisual(DrawingAttributes drawingAttributes)
|
||||
{
|
||||
_drawingAttributes = drawingAttributes;
|
||||
|
||||
|
||||
// 启用硬件加速
|
||||
RenderOptions.SetBitmapScalingMode(this, BitmapScalingMode.HighQuality);
|
||||
RenderOptions.SetEdgeMode(this, EdgeMode.Aliased);
|
||||
@@ -82,7 +82,7 @@ namespace Ink_Canvas.Helpers
|
||||
Stroke.StylusPoints.Add(point);
|
||||
_lastPointCount++;
|
||||
}
|
||||
|
||||
|
||||
// 标记需要重绘
|
||||
_needsRedraw = true;
|
||||
}
|
||||
@@ -93,7 +93,7 @@ namespace Ink_Canvas.Helpers
|
||||
public void Redraw()
|
||||
{
|
||||
if (!_needsRedraw || Stroke == null) return;
|
||||
|
||||
|
||||
if (_lastPointCount % REDRAW_THRESHOLD != 0 && _lastPointCount > REDRAW_THRESHOLD)
|
||||
{
|
||||
return;
|
||||
|
||||
@@ -30,12 +30,12 @@ namespace Ink_Canvas.Helpers
|
||||
private DateTime _inkLockUntil = DateTime.MinValue;
|
||||
private int _lockedSlideIndex = -1;
|
||||
private const int InkLockMilliseconds = 500;
|
||||
|
||||
|
||||
// 添加快速切换保护机制
|
||||
private DateTime _lastSwitchTime = DateTime.MinValue;
|
||||
private int _lastSwitchSlideIndex = -1;
|
||||
private const int MinSwitchIntervalMs = 100; // 最小切换间隔100毫秒
|
||||
|
||||
|
||||
// 内存管理相关字段
|
||||
private long _totalMemoryUsage = 0;
|
||||
private const long MaxMemoryUsageBytes = 100 * 1024 * 1024; // 100MB限制
|
||||
@@ -90,7 +90,7 @@ namespace Ink_Canvas.Helpers
|
||||
{
|
||||
return;
|
||||
}
|
||||
throw;
|
||||
throw;
|
||||
}
|
||||
_memoryStreams = new MemoryStream[slideCount + 2];
|
||||
|
||||
@@ -162,7 +162,7 @@ namespace Ink_Canvas.Helpers
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 强制保存指定页面的墨迹(忽略锁定状态)
|
||||
/// 强制保存指定页面的墨迹
|
||||
/// </summary>
|
||||
public void ForceSaveSlideStrokes(int slideIndex, StrokeCollection strokes)
|
||||
{
|
||||
@@ -238,7 +238,7 @@ namespace Ink_Canvas.Helpers
|
||||
{
|
||||
// 检查快速切换保护
|
||||
var now = DateTime.Now;
|
||||
if (now - _lastSwitchTime < TimeSpan.FromMilliseconds(MinSwitchIntervalMs) &&
|
||||
if (now - _lastSwitchTime < TimeSpan.FromMilliseconds(MinSwitchIntervalMs) &&
|
||||
_lastSwitchSlideIndex == slideIndex)
|
||||
{
|
||||
LogHelper.WriteLogToFile($"快速切换保护:忽略重复的页面切换请求 {slideIndex}", LogHelper.LogType.Warning);
|
||||
@@ -251,11 +251,11 @@ namespace Ink_Canvas.Helpers
|
||||
|
||||
// 加载新页面的墨迹
|
||||
var newStrokes = LoadSlideStrokes(slideIndex);
|
||||
|
||||
|
||||
// 更新切换记录
|
||||
_lastSwitchTime = now;
|
||||
_lastSwitchSlideIndex = slideIndex;
|
||||
|
||||
|
||||
if (newStrokes.Count > 0)
|
||||
{
|
||||
}
|
||||
@@ -300,7 +300,7 @@ namespace Ink_Canvas.Helpers
|
||||
// 保存所有页面的墨迹
|
||||
int savedCount = 0;
|
||||
int slideCount = 0;
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
slideCount = presentation.Slides.Count;
|
||||
@@ -308,13 +308,13 @@ namespace Ink_Canvas.Helpers
|
||||
catch (COMException comEx)
|
||||
{
|
||||
var hr = (uint)comEx.HResult;
|
||||
if (hr == 0x80048010)
|
||||
if (hr == 0x80048010)
|
||||
{
|
||||
return;
|
||||
}
|
||||
throw;
|
||||
throw;
|
||||
}
|
||||
|
||||
|
||||
for (int i = 1; i <= slideCount && i < _memoryStreams.Length; i++)
|
||||
{
|
||||
if (_memoryStreams[i] != null)
|
||||
@@ -430,7 +430,7 @@ namespace Ink_Canvas.Helpers
|
||||
_memoryStreams[i] = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 重新初始化数组
|
||||
_memoryStreams = new MemoryStream[_maxSlides + 2];
|
||||
}
|
||||
@@ -464,20 +464,20 @@ namespace Ink_Canvas.Helpers
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// 如果当前页面与锁定页面相同,允许写入(用户在当前页面绘制)
|
||||
if (currentSlideIndex == _lockedSlideIndex)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// 如果当前页面不是锁定页面,但锁定时间很短(小于50ms),允许写入
|
||||
// 这样可以确保旧页面的墨迹能够及时保存
|
||||
if (DateTime.Now - (_inkLockUntil.AddMilliseconds(-InkLockMilliseconds)) < TimeSpan.FromMilliseconds(50))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// 只有在快速切换且页面不同时才锁定
|
||||
return false;
|
||||
}
|
||||
@@ -504,7 +504,7 @@ namespace Ink_Canvas.Helpers
|
||||
try
|
||||
{
|
||||
var now = DateTime.Now;
|
||||
|
||||
|
||||
// 检查是否需要执行内存清理
|
||||
if (now - _lastMemoryCleanup < TimeSpan.FromMinutes(MemoryCleanupIntervalMinutes))
|
||||
{
|
||||
@@ -530,10 +530,10 @@ namespace Ink_Canvas.Helpers
|
||||
if (currentMemoryUsage > MaxMemoryUsageBytes)
|
||||
{
|
||||
LogHelper.WriteLogToFile($"内存使用量超限 ({currentMemoryUsage / 1024 / 1024}MB),开始清理", LogHelper.LogType.Warning);
|
||||
|
||||
|
||||
// 清理非当前页面的墨迹
|
||||
CleanupInactiveSlideStrokes();
|
||||
|
||||
|
||||
_lastMemoryCleanup = now;
|
||||
LogHelper.WriteLogToFile($"内存清理完成,当前使用量: {_totalMemoryUsage / 1024 / 1024}MB", LogHelper.LogType.Trace);
|
||||
}
|
||||
@@ -571,7 +571,7 @@ namespace Ink_Canvas.Helpers
|
||||
if (_memoryStreams[i] != null)
|
||||
{
|
||||
long memorySize = _memoryStreams[i].Length;
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
_memoryStreams[i].Dispose();
|
||||
|
||||
@@ -678,14 +678,25 @@ namespace Ink_Canvas.Helpers
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!IsConnected || !IsInSlideShow || PPTApplication == null) return false;
|
||||
if (!IsConnected || PPTApplication == null) return false;
|
||||
if (!Marshal.IsComObject(PPTApplication)) return false;
|
||||
|
||||
var slideShowWindow = PPTApplication.SlideShowWindows[1];
|
||||
if (slideShowWindow?.View != null)
|
||||
if (IsInSlideShow && PPTApplication.SlideShowWindows.Count >= 1)
|
||||
{
|
||||
slideShowWindow.View.GotoSlide(slideNumber);
|
||||
return true;
|
||||
var slideShowWindow = PPTApplication.SlideShowWindows[1];
|
||||
if (slideShowWindow?.View != null)
|
||||
{
|
||||
slideShowWindow.View.GotoSlide(slideNumber);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (CurrentPresentation != null)
|
||||
{
|
||||
if (CurrentPresentation.Windows?.Count >= 1)
|
||||
{
|
||||
CurrentPresentation.Windows[1].View.GotoSlide(slideNumber);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Interop;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Threading;
|
||||
|
||||
@@ -96,12 +97,37 @@ namespace Ink_Canvas.Helpers
|
||||
|
||||
UpdateNavigationPanelsVisibility();
|
||||
UpdateNavigationButtonStyles();
|
||||
if (MainWindow.Settings.Advanced.IsEnableAvoidFullScreenHelper)
|
||||
{
|
||||
// 设置为画板模式,允许全屏操作
|
||||
AvoidFullScreenHelper.SetBoardMode(true);
|
||||
_dispatcher.BeginInvoke(new Action(() =>
|
||||
{
|
||||
MainWindow.MoveWindow(new WindowInteropHelper(_mainWindow).Handle, 0, 0,
|
||||
System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width,
|
||||
System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height, true);
|
||||
}), DispatcherPriority.ApplicationIdle);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_mainWindow.BtnPPTSlideShow.Visibility = Visibility.Visible;
|
||||
_mainWindow.BtnPPTSlideShowEnd.Visibility = Visibility.Collapsed;
|
||||
HideAllNavigationPanels();
|
||||
if (MainWindow.Settings.Advanced.IsEnableAvoidFullScreenHelper)
|
||||
{
|
||||
// 恢复为非画板模式,重新启用全屏限制
|
||||
AvoidFullScreenHelper.SetBoardMode(false);
|
||||
|
||||
_dispatcher.BeginInvoke(new Action(() =>
|
||||
{
|
||||
// 退出PPT放映模式,恢复到工作区域大小
|
||||
var workingArea = System.Windows.Forms.Screen.PrimaryScreen.WorkingArea;
|
||||
MainWindow.MoveWindow(new WindowInteropHelper(_mainWindow).Handle,
|
||||
workingArea.X, workingArea.Y,
|
||||
workingArea.Width, workingArea.Height, true);
|
||||
}), DispatcherPriority.ApplicationIdle);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace Ink_Canvas.Helpers
|
||||
|
||||
// 获取窗口在屏幕上的位置
|
||||
var windowRect = GetWindowScreenBounds(window);
|
||||
|
||||
|
||||
// 查找与窗口重叠最多的屏幕
|
||||
Screen targetScreen = null;
|
||||
double maxIntersection = 0;
|
||||
@@ -66,10 +66,10 @@ namespace Ink_Canvas.Helpers
|
||||
{
|
||||
// 获取窗口左上角在屏幕上的位置
|
||||
var topLeft = window.PointToScreen(new Point(0, 0));
|
||||
|
||||
|
||||
// 获取窗口右下角在屏幕上的位置
|
||||
var bottomRight = window.PointToScreen(new Point(window.ActualWidth, window.ActualHeight));
|
||||
|
||||
|
||||
return new Rectangle(
|
||||
(int)topLeft.X,
|
||||
(int)topLeft.Y,
|
||||
|
||||
@@ -0,0 +1,165 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Ink_Canvas.Helpers
|
||||
{
|
||||
/// <summary>
|
||||
/// UIAccess DLL释放器
|
||||
/// </summary>
|
||||
public static class UIAccessDllExtractor
|
||||
{
|
||||
private static readonly string[] RequiredDlls = {
|
||||
"UIAccessDLL_x64.dll",
|
||||
"UIAccessDLL_x86.dll"
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// 在应用启动时释放UIAccess相关DLL
|
||||
/// </summary>
|
||||
public static void ExtractUIAccessDlls()
|
||||
{
|
||||
try
|
||||
{
|
||||
string appDirectory = AppDomain.CurrentDomain.BaseDirectory;
|
||||
LogHelper.WriteLogToFile("开始检查并释放UIAccess相关DLL文件");
|
||||
|
||||
foreach (string dllName in RequiredDlls)
|
||||
{
|
||||
string targetPath = Path.Combine(appDirectory, dllName);
|
||||
|
||||
// 检查文件是否已存在且有效
|
||||
if (File.Exists(targetPath) && IsValidDll(targetPath))
|
||||
{
|
||||
LogHelper.WriteLogToFile($"{dllName} 已存在且有效,跳过释放");
|
||||
continue;
|
||||
}
|
||||
|
||||
// 从嵌入资源中释放DLL
|
||||
if (ExtractDllFromResource(dllName, targetPath))
|
||||
{
|
||||
LogHelper.WriteLogToFile($"成功释放 {dllName} 到 {targetPath}");
|
||||
}
|
||||
else
|
||||
{
|
||||
LogHelper.WriteLogToFile($"警告:无法释放 {dllName},可能影响UIA置顶功能", LogHelper.LogType.Warning);
|
||||
}
|
||||
}
|
||||
|
||||
LogHelper.WriteLogToFile("UIAccess DLL释放检查完成");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogHelper.WriteLogToFile($"释放UIAccess DLL时出错: {ex.Message}", LogHelper.LogType.Error);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从嵌入资源中提取DLL文件
|
||||
/// </summary>
|
||||
private static bool ExtractDllFromResource(string dllName, string targetPath)
|
||||
{
|
||||
try
|
||||
{
|
||||
Assembly assembly = Assembly.GetExecutingAssembly();
|
||||
string resourceName = $"Ink_Canvas.{dllName}";
|
||||
|
||||
using (Stream resourceStream = assembly.GetManifestResourceStream(resourceName))
|
||||
{
|
||||
if (resourceStream == null)
|
||||
{
|
||||
LogHelper.WriteLogToFile($"未找到嵌入资源: {resourceName}", LogHelper.LogType.Warning);
|
||||
return false;
|
||||
}
|
||||
|
||||
// 确保目标目录存在
|
||||
string targetDirectory = Path.GetDirectoryName(targetPath);
|
||||
if (!Directory.Exists(targetDirectory))
|
||||
{
|
||||
Directory.CreateDirectory(targetDirectory);
|
||||
}
|
||||
|
||||
// 写入文件
|
||||
using (FileStream fileStream = new FileStream(targetPath, FileMode.Create, FileAccess.Write))
|
||||
{
|
||||
resourceStream.CopyTo(fileStream);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogHelper.WriteLogToFile($"从资源提取 {dllName} 失败: {ex.Message}", LogHelper.LogType.Error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查DLL文件是否有效
|
||||
/// </summary>
|
||||
private static bool IsValidDll(string filePath)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!File.Exists(filePath))
|
||||
return false;
|
||||
|
||||
FileInfo fileInfo = new FileInfo(filePath);
|
||||
|
||||
// 检查文件大小(空文件或过小的文件可能无效)
|
||||
if (fileInfo.Length < 1024) // 小于1KB可能无效
|
||||
return false;
|
||||
|
||||
// 简单检查PE头(DLL文件应该以MZ开头)
|
||||
using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
|
||||
{
|
||||
byte[] buffer = new byte[2];
|
||||
if (fs.Read(buffer, 0, 2) == 2)
|
||||
{
|
||||
return buffer[0] == 0x4D && buffer[1] == 0x5A; // "MZ"
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清理释放的DLL文件(可选,在应用退出时调用)
|
||||
/// </summary>
|
||||
public static void CleanupExtractedDlls()
|
||||
{
|
||||
try
|
||||
{
|
||||
string appDirectory = AppDomain.CurrentDomain.BaseDirectory;
|
||||
|
||||
foreach (string dllName in RequiredDlls)
|
||||
{
|
||||
string filePath = Path.Combine(appDirectory, dllName);
|
||||
|
||||
if (File.Exists(filePath))
|
||||
{
|
||||
try
|
||||
{
|
||||
File.Delete(filePath);
|
||||
LogHelper.WriteLogToFile($"已清理 {dllName}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogHelper.WriteLogToFile($"清理 {dllName} 失败: {ex.Message}", LogHelper.LogType.Warning);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogHelper.WriteLogToFile($"清理UIAccess DLL时出错: {ex.Message}", LogHelper.LogType.Error);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -192,11 +192,14 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="Resources\TimerDownNotice.wav" />
|
||||
<None Include="Resources\ProgressiveAudio.wav" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Resources\IACore\IACore.dll" />
|
||||
<EmbeddedResource Include="Resources\IACore\IALoader.dll" />
|
||||
<EmbeddedResource Include="Resources\IACore\IAWinFX.dll" />
|
||||
<EmbeddedResource Include="UIAccessDLL_x64.dll" />
|
||||
<EmbeddedResource Include="UIAccessDLL_x86.dll" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="Resources\Cursors\Cursor.cur" />
|
||||
@@ -223,6 +226,10 @@
|
||||
<Resource Include="Resources\Icons-png\icc-transparent-dark.png" />
|
||||
<Resource Include="Resources\Icons-png\icc-transparent.png" />
|
||||
<Resource Include="Resources\Icons-png\icc.png" />
|
||||
<Resource Include="Resources\Icons-png\icc-dark.png" />
|
||||
<Resource Include="Resources\Icons-png\icc-noshadow.png" />
|
||||
<Resource Include="Resources\Icons-png\icc-sharpdark.png" />
|
||||
<Resource Include="Resources\Icons-png\icc-transparent-light-small.png" />
|
||||
<Resource Include="Resources\Icons-png\InkCanvas.png" />
|
||||
<Resource Include="Resources\Icons-png\kuanciya.png" />
|
||||
<Resource Include="Resources\Icons-png\kuandogeyuanliangwo.png" />
|
||||
@@ -239,6 +246,10 @@
|
||||
<Resource Include="Resources\Icons-png\undo.png" />
|
||||
<Resource Include="Resources\Icons-png\minimize.png" />
|
||||
<Resource Include="Resources\Icons-png\penUpright.png" />
|
||||
<Resource Include="Resources\new-icons\multi-touch_white.png" />
|
||||
<Resource Include="Resources\new-icons\hand-move_white.png" />
|
||||
<Resource Include="Resources\new-icons\zoom_white.png" />
|
||||
<Resource Include="Resources\new-icons\rotate_white.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="Resources\Icons-png\twoFingelMove-Blue.png" />
|
||||
@@ -288,7 +299,9 @@
|
||||
<Resource Include="Resources\Icons-Fluent\ic_fluent_arrow_circle_left_24_regular.png" />
|
||||
<Resource Include="Resources\Icons-Fluent\ic_fluent_arrow_circle_right_24_regular.png" />
|
||||
<Resource Include="Resources\Icons-Fluent\ic_fluent_weather_moon_24_regular.png" />
|
||||
<Resource Include="Resources\Icons-Fluent\ic_fluent_weather_moon_24_regular_white.png" />
|
||||
<Resource Include="Resources\Icons-Fluent\ic_fluent_weather_sunny_24_regular.png" />
|
||||
<Resource Include="Resources\Icons-Fluent\ic_fluent_weather_sunny_24_regular_white.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="Resources\Icons-Fluent\ic_fluent_signature_24_regular.png" />
|
||||
@@ -323,6 +336,7 @@
|
||||
<ItemGroup>
|
||||
<Resource Include="Resources\Icons-Fluent\ic_fluent_arrow_rotate_clockwise_24_regular.png" />
|
||||
<Resource Include="Resources\Icons-Fluent\ic_fluent_scale_fit_24_regular.png" />
|
||||
<Resource Include="Resources\Icons-Fluent\ic_fluent_scale_fit_24_regular_white.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="Resources\Icons-Fluent\ic_fluent_scales_24_regular.png" />
|
||||
@@ -340,9 +354,6 @@
|
||||
<ItemGroup>
|
||||
<Resource Include="Resources\Icons-Fluent\ic_fluent_clock_24_regular.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="Resources\Icons-Fluent\ic_fluent_book_question_mark_24_regular.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="Resources\Icons-Fluent\ic_fluent_keyboard_24_regular.png" />
|
||||
</ItemGroup>
|
||||
@@ -410,6 +421,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="Resources\new-icons\gesture.png" />
|
||||
<Resource Include="Resources\new-icons\gesture_white.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="Resources\new-icons\gesture-enabled.png" />
|
||||
@@ -457,6 +469,37 @@
|
||||
<ItemGroup>
|
||||
<Resource Include="Resources\Icons-png\geo-icons\cube.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="Resources\Icons-png\geo-icons\arrow_white.png" />
|
||||
<Resource Include="Resources\Icons-png\geo-icons\dashed-line_white.png" />
|
||||
<Resource Include="Resources\Icons-png\geo-icons\dotted-line_white.png" />
|
||||
<Resource Include="Resources\Icons-png\geo-icons\line_white.png" />
|
||||
<Resource Include="Resources\Icons-png\geo-icons\paralle-lines_white.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="Resources\Icons-png\geo-icons\centered-square_white.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="Resources\Icons-png\geo-icons\centered-circle_white.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="Resources\Icons-png\geo-icons\centered-circle-dashed_white.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="Resources\Icons-png\geo-icons\centered-oval_white.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="Resources\Icons-png\geo-icons\square_white.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="Resources\Icons-png\geo-icons\cylinder_white.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="Resources\Icons-png\geo-icons\cone_white.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="Resources\Icons-png\geo-icons\cube_white.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="Resources\Icons-png\EasiNote.png" />
|
||||
<Resource Include="Resources\Icons-png\EasiNote3C.png" />
|
||||
@@ -502,6 +545,10 @@
|
||||
<Resource Include="Resources\new-icons\eye-light.png" />
|
||||
<Resource Include="Resources\new-icons\chevron-left-light.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="Resources\Icons-Fluent\ic_fluent_keyboard_24_regular_white.png" />
|
||||
<Resource Include="Resources\Icons-Fluent\ic_fluent_control_button_24_regular_white.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Remove="AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
@@ -528,6 +575,10 @@
|
||||
<None Remove="Resources\Icons-png\icc-transparent-dark.png" />
|
||||
<None Remove="Resources\Icons-png\icc-transparent.png" />
|
||||
<None Remove="Resources\Icons-png\icc.png" />
|
||||
<None Remove="Resources\Icons-png\icc-dark.png" />
|
||||
<None Remove="Resources\Icons-png\icc-noshadow.png" />
|
||||
<None Remove="Resources\Icons-png\icc-sharpdark.png" />
|
||||
<None Remove="Resources\Icons-png\icc-transparent-light-small.png" />
|
||||
<None Remove="Resources\Icons-png\idt.png" />
|
||||
<None Remove="Resources\Icons-png\InkCanvas.png" />
|
||||
<None Remove="Resources\Icons-png\kuanciya.png" />
|
||||
@@ -564,6 +615,9 @@
|
||||
<ItemGroup>
|
||||
<Resource Include="Resources\Icons-png\idt.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="Resources\Fonts\LXGWWenKaiTC-Regular.ttf" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="Resources\Icons-png\HiteAnnotation.png" />
|
||||
<Resource Include="Resources\Icons-png\AiClass.png" />
|
||||
@@ -580,6 +634,12 @@
|
||||
<Resource Include="Resources\Startup-animation\ICC Autumn.png" />
|
||||
<Resource Include="Resources\Startup-animation\ICC Winter.png" />
|
||||
<Resource Include="Resources\Startup-animation\ICC Horse.png" />
|
||||
<Resource Include="Resources\Icons-Fluent\ic_fluent_copy_24_regular_white.png" />
|
||||
<Resource Include="Resources\Icons-Fluent\ic_fluent_copy_add_24_regular_white.png" />
|
||||
<Resource Include="Resources\Icons-Fluent\ic_fluent_flip_horizontal_24_regular_white.png" />
|
||||
<Resource Include="Resources\Icons-Fluent\ic_fluent_flip_vertical_24_regular_white.png" />
|
||||
<Resource Include="Resources\Icons-Fluent\ic_fluent_edit_24_regular_white.png" />
|
||||
<Resource Include="Resources\Icons-Fluent\ic_fluent_delete_24_regular_white.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Update="Properties\Settings.Designer.cs">
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<_LastSelectedProfileId>D:\vs\ica\Ink Canvas\Properties\PublishProfiles\FolderProfile.pubxml</_LastSelectedProfileId>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
@@ -40,6 +40,7 @@
|
||||
|
||||
<c:IsEnabledToOpacityConverter x:Key="IsEnabledToOpacityConverter" />
|
||||
<c:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
|
||||
<c:InverseBooleanToVisibilityConverter x:Key="InverseBooleanToVisibilityConverter" />
|
||||
<c:IntNumberToString x:Key="IntNumberToString" />
|
||||
<c:IntNumberToString2 x:Key="IntNumberToString2" />
|
||||
|
||||
@@ -189,12 +190,18 @@
|
||||
<!-- Crash Action -->
|
||||
<Button Width="40" Height="40" Margin="0,5,0,0" Style="{StaticResource NavButton}"
|
||||
Click="NavCrashAction_Click" Tag="crashaction" ToolTip="崩溃处理">
|
||||
<Image Width="24" Height="24">
|
||||
<Image Width="22" Height="22">
|
||||
<Image.Source>
|
||||
<DrawingImage>
|
||||
<DrawingImage.Drawing>
|
||||
<GeometryDrawing Brush="White"
|
||||
Geometry="M13 14H11V9H13M13 18H11V16H13M1 21H23L12 2L1 21Z"/>
|
||||
<GeometryDrawing>
|
||||
<GeometryDrawing.Pen>
|
||||
<Pen Brush="White" Thickness="2" StartLineCap="Round" EndLineCap="Round" LineJoin="Round"/>
|
||||
</GeometryDrawing.Pen>
|
||||
<GeometryDrawing.Geometry>
|
||||
<PathGeometry Figures="M10.863 4.09101L2.75699 17.625C2.58988 17.9144 2.50145 18.2425 2.5005 18.5766C2.49954 18.9108 2.58609 19.2394 2.75153 19.5297C2.91698 19.8201 3.15555 20.062 3.44353 20.2316C3.7315 20.4011 4.05884 20.4923 4.39299 20.496H20.607C20.941 20.4922 21.2682 20.401 21.556 20.2315C21.8438 20.062 22.0823 19.8202 22.2477 19.53C22.4131 19.2398 22.4997 18.9114 22.4989 18.5774C22.4981 18.2434 22.4098 17.9154 22.243 17.626L14.137 4.09001C13.9664 3.80851 13.7262 3.57575 13.4394 3.4142C13.1527 3.25266 12.8291 3.16779 12.5 3.16779C12.1709 3.16779 11.8473 3.25266 11.5605 3.4142C11.2738 3.57575 11.0335 3.80851 10.863 4.09001V4.09101Z M9.5 13.5H15.5"/>
|
||||
</GeometryDrawing.Geometry>
|
||||
</GeometryDrawing>
|
||||
</DrawingImage.Drawing>
|
||||
</DrawingImage>
|
||||
</Image.Source>
|
||||
@@ -603,6 +610,14 @@
|
||||
IsOn="True" FontFamily="Microsoft YaHei UI" FontWeight="Bold"
|
||||
Toggled="ToggleSwitchAlwaysOnTop_Toggled" />
|
||||
</ui:SimpleStackPanel>
|
||||
<ui:SimpleStackPanel Orientation="Horizontal" HorizontalAlignment="Left" Name="UIAccessTopMostPanel" Visibility="Collapsed">
|
||||
<TextBlock Foreground="#fafafa" Text="UIA置顶" VerticalAlignment="Center"
|
||||
FontSize="14" Margin="0,0,16,0" />
|
||||
<ui:ToggleSwitch OnContent="" OffContent="" Name="ToggleSwitchUIAccessTopMost"
|
||||
IsOn="False" FontFamily="Microsoft YaHei UI" FontWeight="Bold"
|
||||
Toggled="ToggleSwitchUIAccessTopMost_Toggled" />
|
||||
</ui:SimpleStackPanel>
|
||||
<TextBlock Name="UIAccessTopMostDescription" Text="# 开启UIA置顶后,软件需要管理员启动才能置顶,关闭此功能需要完全关闭软件后再手动启动,无法使用重启来关闭此功能" TextWrapping="Wrap" Foreground="#a1a1aa" Visibility="Collapsed" />
|
||||
<ui:ToggleSwitch OnContent="" OffContent=""
|
||||
Name="ToggleSwitchIsAutoUpdate" Header="自动检查更新"
|
||||
FontFamily="Microsoft YaHei UI"
|
||||
@@ -625,6 +640,13 @@
|
||||
<TextBlock Text="# 稳定版提供可靠更新,测试版提供新功能抢先体验" TextWrapping="Wrap" Foreground="#a1a1aa" />
|
||||
</ui:SimpleStackPanel>
|
||||
|
||||
<!-- 手动更新按钮 -->
|
||||
<Button x:Name="ManualUpdateButton" Content="手动更新" Margin="0,8,0,0"
|
||||
Width="120" HorizontalAlignment="Left" Click="ManualUpdateButton_Click"
|
||||
Visibility="{Binding ElementName=ToggleSwitchIsAutoUpdate, Path=IsOn, Converter={StaticResource InverseBooleanToVisibilityConverter}}"/>
|
||||
<TextBlock Text="# 点击后立即检查并下载最新版本"
|
||||
TextWrapping="Wrap" Foreground="#a1a1aa"
|
||||
Visibility="{Binding ElementName=ToggleSwitchIsAutoUpdate, Path=IsOn, Converter={StaticResource InverseBooleanToVisibilityConverter}}"/>
|
||||
<!-- 版本修复按钮 -->
|
||||
<Button x:Name="FixVersionButton" Content="版本修复" Margin="0,8,0,0"
|
||||
Width="120" HorizontalAlignment="Left" Click="FixVersionButton_Click"/>
|
||||
@@ -1071,6 +1093,10 @@
|
||||
SelectedIndex="0"
|
||||
SelectionChanged="ComboBoxFloatingBarImg_SelectionChanged">
|
||||
<ComboBoxItem Content="“ICC-CE”默认" FontFamily="Microsoft YaHei UI" />
|
||||
<ComboBoxItem Content="“ICC-CE”无阴影" FontFamily="Microsoft YaHei UI" />
|
||||
<ComboBoxItem Content="“ICC-CE”深色" FontFamily="Microsoft YaHei UI" />
|
||||
<ComboBoxItem Content="“ICC-CE”深色呼吸版" FontFamily="Microsoft YaHei UI" />
|
||||
<ComboBoxItem Content="“ICC-CE”白色透明版" FontFamily="Microsoft YaHei UI" />
|
||||
<ComboBoxItem Content="“ICC-CE”黑色透明版" FontFamily="Microsoft YaHei UI" />
|
||||
<ComboBoxItem Content="酷安斗鸡眼滑稽" FontFamily="Microsoft YaHei UI" />
|
||||
<ComboBoxItem Content="酷安受虐滑稽" FontFamily="Microsoft YaHei UI" />
|
||||
@@ -1464,35 +1490,35 @@
|
||||
FontSize="20" />
|
||||
<Border ClipToBounds="True" Width="324" Height="182">
|
||||
<Grid>
|
||||
<Image Source="Resources/PresentationExample/page.jpg"></Image>
|
||||
<Image Source="Resources/PresentationExample/toolbar.png" Height="16"
|
||||
VerticalAlignment="Bottom" HorizontalAlignment="Center" />
|
||||
<Image Name="PPTBtnPreviewLS" Source="Resources/PresentationExample/sidebar-white.png" Width="10"
|
||||
VerticalAlignment="Center" HorizontalAlignment="Left" RenderTransformOrigin="0.5,0.5" >
|
||||
<Image Source="Resources/PresentationExample/page.jpg" Width="324" Height="182" Stretch="Fill"></Image>
|
||||
<Image Name="PPTBtnPreviewToolbar" Source="Resources/PresentationExample/toolbar.png" Height="16"
|
||||
VerticalAlignment="Bottom" HorizontalAlignment="Center" Stretch="Uniform" />
|
||||
<Image Name="PPTBtnPreviewLS" Source="Resources/PresentationExample/sidebar-white.png" Width="10" Height="30"
|
||||
VerticalAlignment="Center" HorizontalAlignment="Left" RenderTransformOrigin="0.5,0.5" Stretch="Fill">
|
||||
<Image.RenderTransform>
|
||||
<TransformGroup>
|
||||
<TranslateTransform x:Name="PPTBtnPreviewLSTransform"/>
|
||||
</TransformGroup>
|
||||
</Image.RenderTransform>
|
||||
</Image>
|
||||
<Image Name="PPTBtnPreviewRS" Source="Resources/PresentationExample/sidebar-white.png" Width="10"
|
||||
VerticalAlignment="Center" HorizontalAlignment="Right" RenderTransformOrigin="0.5,0.5" >
|
||||
<Image Name="PPTBtnPreviewRS" Source="Resources/PresentationExample/sidebar-white.png" Width="10" Height="30"
|
||||
VerticalAlignment="Center" HorizontalAlignment="Right" RenderTransformOrigin="0.5,0.5" Stretch="Fill">
|
||||
<Image.RenderTransform>
|
||||
<TransformGroup>
|
||||
<TranslateTransform x:Name="PPTBtnPreviewRSTransform"/>
|
||||
</TransformGroup>
|
||||
</Image.RenderTransform>
|
||||
</Image>
|
||||
<Image Name="PPTBtnPreviewLB" Source="Resources/PresentationExample/bottombar-white.png" Height="10"
|
||||
VerticalAlignment="Bottom" HorizontalAlignment="Left" RenderTransformOrigin="0.5,0.5">
|
||||
<Image Name="PPTBtnPreviewLB" Source="Resources/PresentationExample/bottombar-white.png" Height="10" Width="30"
|
||||
VerticalAlignment="Bottom" HorizontalAlignment="Left" RenderTransformOrigin="0.5,0.5" Stretch="Fill">
|
||||
<Image.RenderTransform>
|
||||
<TransformGroup>
|
||||
<TranslateTransform x:Name="PPTBtnPreviewLBTransform"/>
|
||||
</TransformGroup>
|
||||
</Image.RenderTransform>
|
||||
</Image>
|
||||
<Image Name="PPTBtnPreviewRB" Source="Resources/PresentationExample/bottombar-white.png" Height="12"
|
||||
VerticalAlignment="Bottom" HorizontalAlignment="Right" RenderTransformOrigin="0.5,0.5">
|
||||
<Image Name="PPTBtnPreviewRB" Source="Resources/PresentationExample/bottombar-white.png" Height="10" Width="30"
|
||||
VerticalAlignment="Bottom" HorizontalAlignment="Right" RenderTransformOrigin="0.5,0.5" Stretch="Fill">
|
||||
<Image.RenderTransform>
|
||||
<TransformGroup>
|
||||
<TranslateTransform x:Name="PPTBtnPreviewRBTransform"/>
|
||||
@@ -2003,7 +2029,7 @@
|
||||
FontFamily="Microsoft YaHei UI" FontWeight="Bold"
|
||||
Toggled="ToggleSwitchNotifyPreviousPage_Toggled" />
|
||||
</ui:SimpleStackPanel>
|
||||
<TextBlock Text="#开启后会记录上次播放的页数,点击“是”后会在进入放映状态时自动跳转"
|
||||
<TextBlock Text="#开启后会记录上次播放的页数,点击“是”后会自动跳转"
|
||||
TextWrapping="Wrap" Foreground="#a1a1aa" />
|
||||
<ui:SimpleStackPanel Orientation="Horizontal" HorizontalAlignment="Left">
|
||||
<TextBlock Foreground="#fafafa" Text="进入放映时回到首页" VerticalAlignment="Center"
|
||||
@@ -2798,17 +2824,11 @@
|
||||
TextWrapping="Wrap" Foreground="#a1a1aa" Margin="0,0,0,8" />
|
||||
<ui:SimpleStackPanel Orientation="Horizontal" HorizontalAlignment="Left" Margin="0,0,0,8">
|
||||
<Button Name="BtnUnregisterFileAssociation" Content="取消文件关联"
|
||||
Padding="12,6" Margin="0,0,8,0" Click="BtnUnregisterFileAssociation_Click"
|
||||
Background="#FFDC3545" Foreground="White" BorderBrush="#FFBD2130"
|
||||
FontFamily="Microsoft YaHei UI" FontSize="12" />
|
||||
Padding="15,5" Margin="0,0,8,0" Click="BtnUnregisterFileAssociation_Click" />
|
||||
<Button Name="BtnCheckFileAssociation" Content="检查关联状态"
|
||||
Padding="12,6" Margin="0,0,8,0" Click="BtnCheckFileAssociation_Click"
|
||||
Background="#FF17A2B8" Foreground="White" BorderBrush="#FF138496"
|
||||
FontFamily="Microsoft YaHei UI" FontSize="12" />
|
||||
Padding="15,5" Margin="0,0,8,0" Click="BtnCheckFileAssociation_Click" />
|
||||
<Button Name="BtnRegisterFileAssociation" Content="重新注册关联"
|
||||
Padding="12,6" Click="BtnRegisterFileAssociation_Click"
|
||||
Background="#FF28A745" Foreground="White" BorderBrush="#FF1E7E34"
|
||||
FontFamily="Microsoft YaHei UI" FontSize="12" />
|
||||
Padding="15,5" Click="BtnRegisterFileAssociation_Click" />
|
||||
</ui:SimpleStackPanel>
|
||||
<TextBlock Name="TextBlockFileAssociationStatus" Text=""
|
||||
Foreground="#a1a1aa" FontSize="12" Margin="0,4,0,0" />
|
||||
@@ -3057,6 +3077,30 @@
|
||||
Toggled="ToggleSwitchAutoSaveStrokesAtScreenshot_Toggled" />
|
||||
</ui:SimpleStackPanel>
|
||||
|
||||
<ui:SimpleStackPanel Orientation="Horizontal" HorizontalAlignment="Left">
|
||||
<TextBlock Foreground="#fafafa" Text="定时自动保存墨迹" VerticalAlignment="Center"
|
||||
FontSize="14" Margin="0,0,16,0" />
|
||||
<ui:ToggleSwitch OnContent="" OffContent=""
|
||||
Name="ToggleSwitchEnableAutoSaveStrokes" IsOn="False"
|
||||
FontFamily="Microsoft YaHei UI" FontWeight="Bold"
|
||||
Toggled="ToggleSwitchEnableAutoSaveStrokes_Toggled" />
|
||||
</ui:SimpleStackPanel>
|
||||
<ui:SimpleStackPanel Orientation="Horizontal" HorizontalAlignment="Left">
|
||||
<TextBlock Foreground="#a1a1aa" Text="保存间隔" VerticalAlignment="Center"
|
||||
FontSize="12" Margin="0,0,16,0" />
|
||||
<ComboBox Name="ComboBoxAutoSaveStrokesInterval" Width="120"
|
||||
SelectionChanged="ComboBoxAutoSaveStrokesInterval_SelectionChanged">
|
||||
<ComboBoxItem Content="1分钟" Tag="1" />
|
||||
<ComboBoxItem Content="3分钟" Tag="3" />
|
||||
<ComboBoxItem Content="5分钟" Tag="5" />
|
||||
<ComboBoxItem Content="10分钟" Tag="10" />
|
||||
<ComboBoxItem Content="15分钟" Tag="15" />
|
||||
<ComboBoxItem Content="30分钟" Tag="30" />
|
||||
<ComboBoxItem Content="60分钟" Tag="60" />
|
||||
</ComboBox>
|
||||
</ui:SimpleStackPanel>
|
||||
<TextBlock Text="# 开启后将在设定时间间隔自动保存墨迹,仅在画布可见且有墨迹时才会保存" TextWrapping="Wrap" Foreground="#a1a1aa" />
|
||||
|
||||
<ui:SimpleStackPanel Orientation="Horizontal" HorizontalAlignment="Left">
|
||||
<TextBlock Foreground="#fafafa" Text="墨迹全页面保存" VerticalAlignment="Center"
|
||||
FontSize="14" Margin="0,0,16,0" />
|
||||
@@ -3223,6 +3267,15 @@
|
||||
FontWeight="Bold"
|
||||
Toggled="ToggleSwitchShowRandomAndSingleDraw_Toggled" />
|
||||
</ui:SimpleStackPanel>
|
||||
<ui:SimpleStackPanel Orientation="Horizontal" HorizontalAlignment="Left">
|
||||
<TextBlock Foreground="#fafafa" Text="启用快抽悬浮按钮"
|
||||
VerticalAlignment="Center" FontSize="14" Margin="0,0,16,0" />
|
||||
<ui:ToggleSwitch OnContent="" OffContent=""
|
||||
Name="ToggleSwitchEnableQuickDraw"
|
||||
IsOn="True" FontFamily="Microsoft YaHei UI"
|
||||
FontWeight="Bold"
|
||||
Toggled="ToggleSwitchEnableQuickDraw_Toggled" />
|
||||
</ui:SimpleStackPanel>
|
||||
<ui:SimpleStackPanel Orientation="Horizontal" HorizontalAlignment="Left">
|
||||
<TextBlock Foreground="#fafafa" Text="直接调用外部点名"
|
||||
VerticalAlignment="Center" FontSize="14" Margin="0,0,16,0" />
|
||||
@@ -3273,6 +3326,62 @@
|
||||
FontFamily="Consolas"
|
||||
Text="{Binding ElementName=RandWindowOnceMaxStudentsSlider, Path=Value, Converter={StaticResource IntNumberToString}}" />
|
||||
</ui:SimpleStackPanel>
|
||||
|
||||
<!-- 新点名UI设置 -->
|
||||
<Line HorizontalAlignment="Center" X1="0" Y1="0" X2="400" Y2="0"
|
||||
Stroke="#3f3f46" StrokeThickness="1" Margin="0,4,0,4" />
|
||||
<TextBlock Foreground="#fafafa" Text="新点名UI设置"
|
||||
FontSize="16" FontWeight="Bold" Margin="0,10,0,5" />
|
||||
|
||||
<ui:SimpleStackPanel Orientation="Horizontal" HorizontalAlignment="Left">
|
||||
<TextBlock Foreground="#fafafa" Text="启用新点名UI"
|
||||
VerticalAlignment="Center" FontSize="14" Margin="0,0,16,0" />
|
||||
<ui:ToggleSwitch OnContent="" OffContent=""
|
||||
Name="ToggleSwitchUseNewRollCallUI"
|
||||
IsOn="True" FontFamily="Microsoft YaHei UI"
|
||||
FontWeight="Bold"
|
||||
Toggled="ToggleSwitchUseNewRollCallUI_Toggled" />
|
||||
</ui:SimpleStackPanel>
|
||||
|
||||
<ui:SimpleStackPanel Orientation="Horizontal" HorizontalAlignment="Left">
|
||||
<TextBlock Foreground="#fafafa" Text="启用机器学习避免重复"
|
||||
VerticalAlignment="Center" FontSize="14" Margin="0,0,16,0" />
|
||||
<ui:ToggleSwitch OnContent="" OffContent=""
|
||||
Name="ToggleSwitchEnableMLAvoidance"
|
||||
IsOn="True" FontFamily="Microsoft YaHei UI"
|
||||
FontWeight="Bold"
|
||||
Toggled="ToggleSwitchEnableMLAvoidance_Toggled" />
|
||||
</ui:SimpleStackPanel>
|
||||
|
||||
<ui:SimpleStackPanel Orientation="Horizontal" HorizontalAlignment="Left">
|
||||
<TextBlock Foreground="#fafafa" Text="避免重复历史记录数量" VerticalAlignment="Center"
|
||||
FontSize="14" Margin="0,0,16,0" />
|
||||
<Slider x:Name="MLAvoidanceHistorySlider" Minimum="5"
|
||||
Maximum="50" Width="168" FontFamily="Microsoft YaHei UI"
|
||||
ValueChanged="MLAvoidanceHistorySlider_ValueChanged"
|
||||
FontSize="20" IsSnapToTickEnabled="True" Value="20" TickFrequency="5"
|
||||
TickPlacement="None" AutoToolTipPlacement="None" />
|
||||
<TextBlock VerticalAlignment="Center" Margin="12,0,16,0" FontSize="14"
|
||||
FontFamily="Consolas"
|
||||
Text="{Binding ElementName=MLAvoidanceHistorySlider, Path=Value, Converter={StaticResource IntNumberToString}}" />
|
||||
</ui:SimpleStackPanel>
|
||||
|
||||
<ui:SimpleStackPanel Orientation="Horizontal" HorizontalAlignment="Left">
|
||||
<TextBlock Foreground="#fafafa" Text="避免重复权重" VerticalAlignment="Center"
|
||||
FontSize="14" Margin="0,0,16,0" />
|
||||
<Slider x:Name="MLAvoidanceWeightSlider" Minimum="0.1"
|
||||
Maximum="1.0" Width="168" FontFamily="Microsoft YaHei UI"
|
||||
ValueChanged="MLAvoidanceWeightSlider_ValueChanged"
|
||||
FontSize="20" IsSnapToTickEnabled="True" Value="0.8" TickFrequency="0.1"
|
||||
TickPlacement="None" AutoToolTipPlacement="None" />
|
||||
<TextBlock VerticalAlignment="Center" Margin="12,0,16,0" FontSize="14"
|
||||
FontFamily="Consolas"
|
||||
Text="{Binding ElementName=MLAvoidanceWeightSlider, Path=Value, StringFormat={}{0:P0}}" />
|
||||
</ui:SimpleStackPanel>
|
||||
|
||||
<TextBlock Text="# 机器学习算法会分析最近的点名历史,智能避免重复选择相同人员"
|
||||
TextWrapping="Wrap" Foreground="#a1a1aa" Margin="0,5,0,0" />
|
||||
|
||||
<Line HorizontalAlignment="Center" X1="0" Y1="0" X2="400" Y2="0"
|
||||
Stroke="#3f3f46" StrokeThickness="1" Margin="0,4,0,4" />
|
||||
<TextBlock Foreground="#fafafa" Text="计时器设置"
|
||||
@@ -3286,6 +3395,33 @@
|
||||
FontWeight="Bold"
|
||||
Toggled="ToggleSwitchUseLegacyTimerUI_Toggled" />
|
||||
</ui:SimpleStackPanel>
|
||||
<ui:SimpleStackPanel Orientation="Horizontal" HorizontalAlignment="Left">
|
||||
<TextBlock Foreground="#fafafa" Text="新计时器UI"
|
||||
VerticalAlignment="Center" FontSize="14" Margin="0,0,16,0" />
|
||||
<ui:ToggleSwitch OnContent="" OffContent=""
|
||||
Name="ToggleSwitchUseNewStyleUI"
|
||||
IsOn="False" FontFamily="Microsoft YaHei UI"
|
||||
FontWeight="Bold"
|
||||
Toggled="ToggleSwitchUseNewStyleUI_Toggled" />
|
||||
</ui:SimpleStackPanel>
|
||||
<ui:SimpleStackPanel Orientation="Horizontal" HorizontalAlignment="Left">
|
||||
<TextBlock Foreground="#fafafa" Text="启用正计时"
|
||||
VerticalAlignment="Center" FontSize="14" Margin="0,0,16,0" />
|
||||
<ui:ToggleSwitch OnContent="" OffContent=""
|
||||
Name="ToggleSwitchEnableOvertimeCountUp"
|
||||
IsOn="False" FontFamily="Microsoft YaHei UI"
|
||||
FontWeight="Bold"
|
||||
Toggled="ToggleSwitchEnableOvertimeCountUp_Toggled" />
|
||||
</ui:SimpleStackPanel>
|
||||
<ui:SimpleStackPanel Orientation="Horizontal" HorizontalAlignment="Left">
|
||||
<TextBlock Foreground="#fafafa" Text="超时醒目数字"
|
||||
VerticalAlignment="Center" FontSize="14" Margin="0,0,16,0" />
|
||||
<ui:ToggleSwitch OnContent="" OffContent=""
|
||||
Name="ToggleSwitchEnableOvertimeRedText"
|
||||
IsOn="True" FontFamily="Microsoft YaHei UI"
|
||||
FontWeight="Bold"
|
||||
Toggled="ToggleSwitchEnableOvertimeRedText_Toggled" />
|
||||
</ui:SimpleStackPanel>
|
||||
<ui:SimpleStackPanel Orientation="Horizontal" HorizontalAlignment="Left">
|
||||
<TextBlock Foreground="#fafafa" Text="计时器提醒音量" VerticalAlignment="Center"
|
||||
FontSize="14" Margin="0,0,16,0" />
|
||||
@@ -3306,6 +3442,35 @@
|
||||
<Button Name="ButtonResetTimerSound" Content="重置" FontFamily="Microsoft YaHei UI"
|
||||
Click="ButtonResetTimerSound_Click" Padding="10,3" Margin="5,0,0,0"/>
|
||||
</ui:SimpleStackPanel>
|
||||
<ui:SimpleStackPanel Orientation="Horizontal" HorizontalAlignment="Left" Margin="0,5,0,0">
|
||||
<TextBlock Foreground="#fafafa" Text="渐进提醒" VerticalAlignment="Center"
|
||||
FontSize="14" Margin="0,0,16,0" />
|
||||
<ui:ToggleSwitch OnContent="" OffContent=""
|
||||
Name="ToggleSwitchEnableProgressiveReminder"
|
||||
IsOn="False" FontFamily="Microsoft YaHei UI"
|
||||
FontWeight="Bold"
|
||||
Toggled="ToggleSwitchEnableProgressiveReminder_Toggled" />
|
||||
</ui:SimpleStackPanel>
|
||||
<ui:SimpleStackPanel Orientation="Horizontal" HorizontalAlignment="Left" Margin="0,5,0,0">
|
||||
<TextBlock Foreground="#fafafa" Text="渐进提醒音量" VerticalAlignment="Center"
|
||||
FontSize="14" Margin="0,0,16,0" />
|
||||
<Slider x:Name="ProgressiveReminderVolumeSlider" Minimum="0"
|
||||
Maximum="1" Width="168" FontFamily="Microsoft YaHei UI"
|
||||
ValueChanged="ProgressiveReminderVolumeSlider_ValueChanged"
|
||||
FontSize="20" IsSnapToTickEnabled="True" Value="1" TickFrequency="0.1"
|
||||
TickPlacement="None" AutoToolTipPlacement="None" />
|
||||
<TextBlock VerticalAlignment="Center" Margin="12,0,16,0" FontSize="14"
|
||||
FontFamily="Consolas"
|
||||
Text="{Binding ElementName=ProgressiveReminderVolumeSlider, Path=Value, StringFormat={}{0:P0}}" />
|
||||
</ui:SimpleStackPanel>
|
||||
<ui:SimpleStackPanel Orientation="Horizontal" HorizontalAlignment="Left" Margin="0,5,0,0">
|
||||
<TextBlock Foreground="#fafafa" Text="自定义渐进提醒音频:" VerticalAlignment="Center"
|
||||
FontSize="14" Margin="0,0,16,0" />
|
||||
<Button Name="ButtonSelectCustomProgressiveReminderSound" Content="选择文件" FontFamily="Microsoft YaHei UI"
|
||||
Click="ButtonSelectCustomProgressiveReminderSound_Click" Padding="10,3"/>
|
||||
<Button Name="ButtonResetProgressiveReminderSound" Content="重置" FontFamily="Microsoft YaHei UI"
|
||||
Click="ButtonResetProgressiveReminderSound_Click" Padding="10,3" Margin="5,0,0,0"/>
|
||||
</ui:SimpleStackPanel>
|
||||
</ui:SimpleStackPanel>
|
||||
</GroupBox>
|
||||
<GroupBox>
|
||||
@@ -3855,7 +4020,7 @@
|
||||
CornerRadius="{Binding ElementName=BorderStrokeSelectionControl, Path=CornerRadius}"
|
||||
Width="40" MouseDown="Border_MouseDown" MouseUp="BorderStrokeSelectionClone_MouseUp">
|
||||
<ui:SimpleStackPanel VerticalAlignment="Center" HorizontalAlignment="Center">
|
||||
<Image Source="/Resources/Icons-Fluent/ic_fluent_copy_24_regular.png"
|
||||
<Image Source="{DynamicResource StrokeSelectionCloneIcon}"
|
||||
RenderOptions.BitmapScalingMode="HighQuality" Height="25" Width="25" />
|
||||
<TextBlock Text="克隆" FontSize="10" Foreground="{DynamicResource FloatBarForeground}"
|
||||
HorizontalAlignment="Center" />
|
||||
@@ -3867,7 +4032,7 @@
|
||||
MouseUp="BorderStrokeSelectionCloneToNewBoard_MouseUp"
|
||||
Visibility="{Binding Visibility, ElementName=GridBackgroundCover}">
|
||||
<ui:SimpleStackPanel VerticalAlignment="Center" HorizontalAlignment="Center">
|
||||
<Image Source="/Resources/Icons-Fluent/ic_fluent_copy_add_24_regular.png"
|
||||
<Image Source="{DynamicResource StrokeSelectionCloneToNewBoardIcon}"
|
||||
RenderOptions.BitmapScalingMode="HighQuality" Height="25" Width="25" />
|
||||
<TextBlock Text="克隆至新页" FontSize="8" Foreground="{DynamicResource FloatBarForeground}"
|
||||
HorizontalAlignment="Center" />
|
||||
@@ -3895,10 +4060,10 @@
|
||||
<ui:SimpleStackPanel VerticalAlignment="Center" Margin="0,-10">
|
||||
<ui:SimpleStackPanel Orientation="Horizontal">
|
||||
<Image MouseDown="Border_MouseDown" MouseUp="ImageFlipHorizontal_MouseUp"
|
||||
Source="/Resources/Icons-Fluent/ic_fluent_flip_horizontal_24_regular.png"
|
||||
Source="{DynamicResource StrokeSelectionFlipHorizontalIcon}"
|
||||
RenderOptions.BitmapScalingMode="HighQuality" Height="30" Width="30" />
|
||||
<Image MouseDown="Border_MouseDown" MouseUp="ImageFlipVertical_MouseUp"
|
||||
Source="/Resources/Icons-Fluent/ic_fluent_flip_vertical_24_regular.png"
|
||||
Source="{DynamicResource StrokeSelectionFlipVerticalIcon}"
|
||||
RenderOptions.BitmapScalingMode="HighQuality" Height="30" Width="30" />
|
||||
</ui:SimpleStackPanel>
|
||||
<TextBlock Text="翻转" FontSize="10" HorizontalAlignment="Center"
|
||||
@@ -3912,21 +4077,21 @@
|
||||
<ui:SimpleStackPanel VerticalAlignment="Center" Spacing="5" Margin="0,-10">
|
||||
<ui:SimpleStackPanel Orientation="Horizontal" Spacing="5">
|
||||
<Grid MouseDown="Border_MouseDown" MouseUp="GridPenWidthDecrease_MouseUp">
|
||||
<Image Source="/Resources/Icons-Fluent/ic_fluent_edit_24_regular.png"
|
||||
<Image Source="{DynamicResource StrokeSelectionPenWidthIcon}"
|
||||
RenderOptions.BitmapScalingMode="HighQuality" Height="25" Width="25" />
|
||||
<TextBlock Text="-" Foreground="{DynamicResource FloatBarForeground}"
|
||||
VerticalAlignment="Bottom" HorizontalAlignment="Right"
|
||||
Margin="0,0,-2,-7" FontSize="15" />
|
||||
</Grid>
|
||||
<Grid MouseDown="Border_MouseDown" MouseUp="GridPenWidthIncrease_MouseUp">
|
||||
<Image Source="/Resources/Icons-Fluent/ic_fluent_edit_24_regular.png"
|
||||
<Image Source="{DynamicResource StrokeSelectionPenWidthIcon}"
|
||||
RenderOptions.BitmapScalingMode="HighQuality" Height="25" Width="25" />
|
||||
<TextBlock Text="+" Foreground="{DynamicResource FloatBarForeground}"
|
||||
VerticalAlignment="Bottom" HorizontalAlignment="Right"
|
||||
Margin="0,0,-3,-4" FontSize="11" />
|
||||
</Grid>
|
||||
<Grid MouseDown="Border_MouseDown" MouseUp="GridPenWidthRestore_MouseUp">
|
||||
<Image Source="/Resources/Icons-Fluent/ic_fluent_edit_24_regular.png"
|
||||
<Image Source="{DynamicResource StrokeSelectionPenWidthIcon}"
|
||||
RenderOptions.BitmapScalingMode="HighQuality" Height="25" Width="25" />
|
||||
<Image Source="{DynamicResource AndroidRefreshDrawingImage}"
|
||||
VerticalAlignment="Bottom" HorizontalAlignment="Right"
|
||||
@@ -3943,7 +4108,7 @@
|
||||
CornerRadius="{Binding ElementName=BorderStrokeSelectionControl, Path=CornerRadius}"
|
||||
Width="40" MouseDown="Border_MouseDown" MouseUp="BorderStrokeSelectionDelete_MouseUp">
|
||||
<ui:SimpleStackPanel VerticalAlignment="Center" HorizontalAlignment="Center">
|
||||
<Image Source="/Resources/Icons-Fluent/ic_fluent_delete_24_regular.png"
|
||||
<Image Source="{DynamicResource StrokeSelectionDeleteIcon}"
|
||||
RenderOptions.BitmapScalingMode="HighQuality" Height="25" Width="25" />
|
||||
<TextBlock Margin="0,5,0,0" Text="删除" FontSize="10"
|
||||
Foreground="{DynamicResource FloatBarForeground}"
|
||||
@@ -3967,7 +4132,7 @@
|
||||
CornerRadius="{Binding ElementName=BorderImageSelectionControl, Path=CornerRadius}"
|
||||
Width="40" MouseDown="Border_MouseDown" MouseUp="BorderImageClone_MouseUp">
|
||||
<ui:SimpleStackPanel VerticalAlignment="Center" HorizontalAlignment="Center">
|
||||
<Image Source="/Resources/Icons-Fluent/ic_fluent_copy_24_regular.png"
|
||||
<Image Source="{DynamicResource ImageSelectionCloneIcon}"
|
||||
RenderOptions.BitmapScalingMode="HighQuality" Height="25" Width="25" />
|
||||
<TextBlock Text="克隆" FontSize="10" Foreground="{DynamicResource FloatBarForeground}"
|
||||
HorizontalAlignment="Center" />
|
||||
@@ -3983,7 +4148,7 @@
|
||||
Visibility="{Binding Visibility, ElementName=GridBackgroundCover}">
|
||||
<ui:SimpleStackPanel VerticalAlignment="Center"
|
||||
HorizontalAlignment="Center">
|
||||
<Image Source="/Resources/Icons-Fluent/ic_fluent_copy_add_24_regular.png"
|
||||
<Image Source="{DynamicResource ImageSelectionCloneToNewBoardIcon}"
|
||||
RenderOptions.BitmapScalingMode="HighQuality"
|
||||
Height="25"
|
||||
Width="25" />
|
||||
@@ -4026,14 +4191,14 @@
|
||||
<ui:SimpleStackPanel VerticalAlignment="Center" Spacing="5" Margin="0,-10">
|
||||
<ui:SimpleStackPanel Orientation="Horizontal" Spacing="10">
|
||||
<Grid MouseDown="Border_MouseDown" MouseUp="GridImageScaleDecrease_MouseUp">
|
||||
<Image Source="/Resources/Icons-Fluent/ic_fluent_scale_fit_24_regular.png"
|
||||
<Image Source="{DynamicResource ImageSelectionScaleIcon1}"
|
||||
RenderOptions.BitmapScalingMode="HighQuality" Height="25" Width="25" />
|
||||
<TextBlock Text="-" Foreground="{DynamicResource FloatBarForeground}"
|
||||
VerticalAlignment="Bottom" HorizontalAlignment="Right"
|
||||
Margin="0,0,-2,-7" FontSize="15" />
|
||||
</Grid>
|
||||
<Grid MouseDown="Border_MouseDown" MouseUp="GridImageScaleIncrease_MouseUp">
|
||||
<Image Source="/Resources/Icons-Fluent/ic_fluent_scale_fit_24_regular.png"
|
||||
<Image Source="{DynamicResource ImageSelectionScaleIcon2}"
|
||||
RenderOptions.BitmapScalingMode="HighQuality" Height="25" Width="25" />
|
||||
<TextBlock Text="+" Foreground="{DynamicResource FloatBarForeground}"
|
||||
VerticalAlignment="Bottom" HorizontalAlignment="Right"
|
||||
@@ -4050,7 +4215,7 @@
|
||||
CornerRadius="{Binding ElementName=BorderImageSelectionControl, Path=CornerRadius}"
|
||||
Width="40" MouseDown="Border_MouseDown" MouseUp="BorderImageDelete_MouseUp">
|
||||
<ui:SimpleStackPanel VerticalAlignment="Center" HorizontalAlignment="Center">
|
||||
<Image Source="/Resources/Icons-Fluent/ic_fluent_delete_24_regular.png"
|
||||
<Image Source="{DynamicResource ImageSelectionDeleteIcon}"
|
||||
RenderOptions.BitmapScalingMode="HighQuality" Height="25" Width="25" />
|
||||
<TextBlock Margin="0,5,0,0" Text="删除" FontSize="10"
|
||||
Foreground="{DynamicResource FloatBarForeground}"
|
||||
@@ -4399,7 +4564,7 @@
|
||||
VerticalAlignment="Center"
|
||||
HorizontalAlignment="Center"
|
||||
Margin="0,3,0,0">
|
||||
<Image Source="/Resources/new-icons/multi-touch.png"
|
||||
<Image Source="{DynamicResource MultiTouchIcon}"
|
||||
RenderOptions.BitmapScalingMode="HighQuality"
|
||||
Height="16"
|
||||
Width="16" />
|
||||
@@ -4430,7 +4595,7 @@
|
||||
Orientation="Horizontal" Spacing="4"
|
||||
VerticalAlignment="Center"
|
||||
HorizontalAlignment="Center">
|
||||
<Image Source="/Resources/new-icons/hand-move.png"
|
||||
<Image Source="{DynamicResource HandMoveIcon}"
|
||||
RenderOptions.BitmapScalingMode="HighQuality"
|
||||
Height="16"
|
||||
Width="16" />
|
||||
@@ -4461,7 +4626,7 @@
|
||||
Orientation="Horizontal" Spacing="4"
|
||||
VerticalAlignment="Center"
|
||||
HorizontalAlignment="Center">
|
||||
<Image Source="/Resources/new-icons/zoom.png"
|
||||
<Image Source="{DynamicResource ZoomIcon}"
|
||||
RenderOptions.BitmapScalingMode="HighQuality"
|
||||
Height="16"
|
||||
Width="16" />
|
||||
@@ -4490,7 +4655,7 @@
|
||||
Orientation="Horizontal" Spacing="4"
|
||||
VerticalAlignment="Center"
|
||||
HorizontalAlignment="Center">
|
||||
<Image Source="/Resources/new-icons/rotate.png"
|
||||
<Image Source="{DynamicResource RotateIcon}"
|
||||
RenderOptions.BitmapScalingMode="HighQuality"
|
||||
Height="16"
|
||||
Width="16" />
|
||||
@@ -4859,7 +5024,7 @@
|
||||
<Controls:UniformGrid Columns="5"
|
||||
Width="270"
|
||||
Margin="0">
|
||||
<Border BorderBrush="Black"
|
||||
<Border BorderBrush="{DynamicResource FloatBarBorderBrush}"
|
||||
BorderThickness="1"
|
||||
CornerRadius="100" Width="45"
|
||||
MouseDown="Border_MouseDown"
|
||||
@@ -4885,7 +5050,7 @@
|
||||
<Border
|
||||
x:Name="BoardBorderPenColorBlack"
|
||||
Background="Black"
|
||||
BorderBrush="Black"
|
||||
BorderBrush="#D3D3D3"
|
||||
BorderThickness="1.5"
|
||||
CornerRadius="100"
|
||||
Width="45"
|
||||
@@ -5568,7 +5733,7 @@
|
||||
Margin="0,0,0,0" Spacing="4">
|
||||
<Border x:Name="BoardCircleEraserTabButton"
|
||||
MouseDown="SwitchToCircleEraser"
|
||||
Background="#553b82f6" Height="20" Width="40"
|
||||
Background="{DynamicResource BoardFloatBarButtonBackgroundPointerOverKey}" Height="20" Width="40"
|
||||
CornerRadius="3">
|
||||
<Canvas>
|
||||
<ui:SimpleStackPanel
|
||||
@@ -5576,7 +5741,7 @@
|
||||
Visibility="Visible" Orientation="Horizontal"
|
||||
Canvas.Left="11" Canvas.Right="11"
|
||||
Canvas.Bottom="0">
|
||||
<Border Width="18" Height="2" Background="#2563eb"
|
||||
<Border Width="18" Height="2" Background="{DynamicResource BoardFloatBarButtonButtonBackgroundPressedKey}"
|
||||
CornerRadius="1" />
|
||||
</ui:SimpleStackPanel>
|
||||
<ui:SimpleStackPanel Orientation="Vertical" Height="20"
|
||||
@@ -5586,24 +5751,23 @@
|
||||
HorizontalAlignment="Center" Margin="0,3">
|
||||
<TextBlock
|
||||
x:Name="BoardCircleEraserTabButtonText"
|
||||
Foreground="#172554" FontWeight="Medium"
|
||||
Foreground="{DynamicResource FloatBarForeground}" FontWeight="Medium"
|
||||
FontSize="9" TextAlignment="Center"
|
||||
Text="圆形擦"
|
||||
Margin="2,1,0,0" />
|
||||
Text="圆形擦" />
|
||||
</ui:SimpleStackPanel>
|
||||
</ui:SimpleStackPanel>
|
||||
</Canvas>
|
||||
</Border>
|
||||
<Border x:Name="BoardRectangleEraserTabButton"
|
||||
MouseDown="SwitchToRectangleEraser"
|
||||
Background="Transparent"
|
||||
Background="{DynamicResource BoardFloatBarButtonBackgroundKey}"
|
||||
Height="20" Width="40" CornerRadius="3">
|
||||
<Canvas>
|
||||
<ui:SimpleStackPanel Visibility="Collapsed"
|
||||
x:Name="BoardRectangleEraserTabButtonIndicator"
|
||||
Orientation="Horizontal" Canvas.Left="11"
|
||||
Canvas.Right="11" Canvas.Bottom="0">
|
||||
<Border Width="18" Height="2" Background="#2563eb"
|
||||
<Border Width="18" Height="2" Background="{DynamicResource BoardFloatBarButtonButtonBackgroundPressedKey}"
|
||||
CornerRadius="1" />
|
||||
</ui:SimpleStackPanel>
|
||||
<ui:SimpleStackPanel Orientation="Vertical" Height="20"
|
||||
@@ -5613,10 +5777,9 @@
|
||||
HorizontalAlignment="Center" Margin="0,3">
|
||||
<TextBlock
|
||||
x:Name="BoardRectangleEraserTabButtonText"
|
||||
Foreground="#172554" FontWeight="Medium"
|
||||
Foreground="{DynamicResource FloatBarForeground}" FontWeight="Medium"
|
||||
FontSize="9" TextAlignment="Center"
|
||||
Text="黑板擦"
|
||||
Margin="2,1,0,0" />
|
||||
Text="黑板擦" />
|
||||
</ui:SimpleStackPanel>
|
||||
</ui:SimpleStackPanel>
|
||||
</Canvas>
|
||||
@@ -5954,7 +6117,7 @@
|
||||
</Image.Source>
|
||||
</Image>
|
||||
<TextBlock Text="截图" FontSize="10"
|
||||
Foreground="#1f2937" VerticalAlignment="Center"/>
|
||||
Foreground="{DynamicResource TextForeground}" VerticalAlignment="Center"/>
|
||||
</ui:SimpleStackPanel>
|
||||
</Border>
|
||||
<!-- Select Image Option -->
|
||||
@@ -5984,7 +6147,7 @@
|
||||
</Image.Source>
|
||||
</Image>
|
||||
<TextBlock Text="选择图片" FontSize="10"
|
||||
Foreground="#1f2937" VerticalAlignment="Center"/>
|
||||
Foreground="{DynamicResource TextForeground}" VerticalAlignment="Center"/>
|
||||
</ui:SimpleStackPanel>
|
||||
</Border>
|
||||
</ui:SimpleStackPanel>
|
||||
@@ -7632,14 +7795,14 @@
|
||||
<DrawingImage>
|
||||
<DrawingImage.Drawing>
|
||||
<DrawingGroup ClipGeometry="M0,0 V24 H24 V0 H0 Z">
|
||||
<GeometryDrawing x:Name="ClearIconGeometry" Brush="#b91c1c"
|
||||
<GeometryDrawing x:Name="ClearIconGeometry" Brush="{DynamicResource RedBrush}"
|
||||
Geometry="F1 M24,24z M0,0z M8.53333,2.37333L7.92,4.21333 2.56,4.21333C2.4,4.21333 2.26667,4.27556 2.16,4.4 2.05333,4.50667 2,4.63111 2,4.77333L2,5.89333C2,6.03556 2.05333,6.16889 2.16,6.29333 2.26667,6.4 2.4,6.45333 2.56,6.45333L21.44,6.45333C21.6,6.45333 21.7333,6.4 21.84,6.29333 21.9467,6.16889 22,6.03556 22,5.89333L22,4.77333C22,4.63111 21.9467,4.50667 21.84,4.4 21.7333,4.27556 21.6,4.21333 21.44,4.21333L16.08,4.21333 15.4667,2.37333C15.4311,2.26667 15.36,2.17778 15.2533,2.10667 15.1644,2.03556 15.0578,2 14.9333,2L9.06667,2C8.94222,2 8.82667,2.03556 8.72,2.10667 8.63111,2.17778 8.56889,2.26667 8.53333,2.37333z M19.7867,8.10667L18.7467,20.9867C18.7111,21.2711 18.5867,21.5111 18.3733,21.7067 18.1778,21.9022 17.9378,22 17.6533,22L6.37333,22C6.08889,22 5.84,21.9022 5.62667,21.7067 5.41333,21.5111 5.28889,21.2711 5.25333,20.9867L4.21333,8.10667 19.7867,8.10667z M8.66667,12.56L8.66667,16.9867C8.66667,17.1467 8.72,17.28 8.82667,17.3867 8.93333,17.4933 9.06667,17.5467 9.22667,17.5467L9.78667,17.5467C9.92889,17.5467 10.0533,17.4933 10.16,17.3867 10.2844,17.28 10.3467,17.1467 10.3467,16.9867L10.3467,12.56C10.3467,12.4 10.2844,12.2667 10.16,12.16 10.0533,12.0533 9.92889,12 9.78667,12L9.22667,12C9.06667,12 8.93333,12.0533 8.82667,12.16 8.72,12.2667 8.66667,12.4 8.66667,12.56z M14.2133,12C14.0711,12 13.9467,12.0533 13.84,12.16 13.7333,12.2667 13.68,12.4 13.68,12.56L13.68,16.9867C13.68,17.1467 13.7333,17.28 13.84,17.3867 13.9467,17.4933 14.0711,17.5467 14.2133,17.5467L14.7733,17.5467C14.9333,17.5467 15.0667,17.4933 15.1733,17.3867 15.28,17.28 15.3333,17.1467 15.3333,16.9867L15.3333,12.56C15.3333,12.4 15.28,12.2667 15.1733,12.16 15.0667,12.0533 14.9333,12 14.7733,12L14.2133,12z" />
|
||||
</DrawingGroup>
|
||||
</DrawingImage.Drawing>
|
||||
</DrawingImage>
|
||||
</Image.Source>
|
||||
</Image>
|
||||
<TextBlock x:Name="TrashBinToolbarTextBlock" Text="清空" Foreground="#B91C1C"
|
||||
<TextBlock x:Name="TrashBinToolbarTextBlock" Text="清空" Foreground="{DynamicResource RedBrush}"
|
||||
FontWeight="Bold" FontSize="8" Margin="0,1,0,0" TextAlignment="Center" />
|
||||
</ui:SimpleStackPanel>
|
||||
<ui:SimpleStackPanel Name="StackPanelCanvasControls" Visibility="Visible"
|
||||
@@ -7869,7 +8032,7 @@
|
||||
Orientation="Horizontal" Width="270">
|
||||
<Controls:UniformGrid Columns="5" Width="270"
|
||||
Margin="0">
|
||||
<Border BorderBrush="Black"
|
||||
<Border BorderBrush="{DynamicResource FloatBarBorderBrush}"
|
||||
BorderThickness="1"
|
||||
CornerRadius="100" Width="45"
|
||||
MouseDown="Border_MouseDown"
|
||||
@@ -7891,7 +8054,7 @@
|
||||
</Grid>
|
||||
</Border>
|
||||
<Border x:Name="BorderPenColorBlack"
|
||||
Background="Black" BorderBrush="Black"
|
||||
Background="Black" BorderBrush="#D3D3D3"
|
||||
BorderThickness="1.5"
|
||||
CornerRadius="100"
|
||||
Width="45"
|
||||
@@ -8560,7 +8723,7 @@
|
||||
MouseDown="Image_MouseDown"
|
||||
MouseUp="BtnDrawLine_Click" Margin="0,0,0,0"
|
||||
Height="38" Width="32" Orientation="Vertical">
|
||||
<Image Source="/Resources/Icons-png/geo-icons/line.png"
|
||||
<Image Source="{DynamicResource GeoIconLine}"
|
||||
RenderOptions.BitmapScalingMode="HighQuality"
|
||||
Margin="0,4,0,2" Height="19" Width="19" />
|
||||
<Label Content="画直线" FontSize="8" HorizontalAlignment="Center" />
|
||||
@@ -8570,7 +8733,7 @@
|
||||
MouseUp="BtnDrawDashedLine_Click"
|
||||
Margin="0,0,0,0"
|
||||
Height="38" Width="32" Orientation="Vertical">
|
||||
<Image Source="/Resources/Icons-png/geo-icons/dashed-line.png"
|
||||
<Image Source="{DynamicResource GeoIconDashedLine}"
|
||||
RenderOptions.BitmapScalingMode="HighQuality"
|
||||
Margin="0,4,0,2" Height="19" Width="19" />
|
||||
<Label Content="画虚线" FontSize="8" HorizontalAlignment="Center" />
|
||||
@@ -8580,7 +8743,7 @@
|
||||
MouseUp="BtnDrawDotLine_Click"
|
||||
Margin="0,0,0,0"
|
||||
Height="38" Width="32" Orientation="Vertical">
|
||||
<Image Source="/Resources/Icons-png/geo-icons/dotted-line.png"
|
||||
<Image Source="{DynamicResource GeoIconDotLine}"
|
||||
RenderOptions.BitmapScalingMode="HighQuality"
|
||||
Margin="0,4,0,2" Height="19" Width="19" />
|
||||
<Label Content="画点线" FontSize="8" HorizontalAlignment="Center" />
|
||||
@@ -8589,7 +8752,7 @@
|
||||
MouseDown="Image_MouseDown"
|
||||
MouseUp="BtnDrawArrow_Click" Margin="0,0,0,0"
|
||||
Height="38" Width="32" Orientation="Vertical">
|
||||
<Image Source="/Resources/Icons-png/geo-icons/arrow.png"
|
||||
<Image Source="{DynamicResource GeoIconArrow}"
|
||||
RenderOptions.BitmapScalingMode="HighQuality"
|
||||
Margin="0,4,0,2" Height="19" Width="19" />
|
||||
<Label Content="画箭头" FontSize="8" HorizontalAlignment="Center" />
|
||||
@@ -8600,7 +8763,7 @@
|
||||
Margin="0,0,0,0" Height="38" Width="32"
|
||||
Orientation="Vertical">
|
||||
<Image
|
||||
Source="/Resources/Icons-png/geo-icons/paralle-lines.png"
|
||||
Source="{DynamicResource GeoIconParallelLine}"
|
||||
RenderOptions.BitmapScalingMode="HighQuality"
|
||||
Margin="0,4,0,2" Height="19" Width="19" />
|
||||
<Label Content="4平行线" FontSize="8" HorizontalAlignment="Center" />
|
||||
@@ -8609,7 +8772,7 @@
|
||||
Margin="0,0,0,0" Height="38" Width="32"
|
||||
Orientation="Vertical">
|
||||
<Image
|
||||
Source="/Resources/Icons-png/geo-icons/centered-square.png"
|
||||
Source="{DynamicResource GeoIconRectangleCenter}"
|
||||
RenderOptions.BitmapScalingMode="HighQuality"
|
||||
Margin="0,4,0,2" Height="19" Width="19" />
|
||||
<Label Content="中心正方" FontSize="8" HorizontalAlignment="Center" />
|
||||
@@ -8617,7 +8780,7 @@
|
||||
<ui:SimpleStackPanel MouseUp="BtnDrawCircle_Click" Margin="0,0,0,0"
|
||||
Height="38" Width="32" Orientation="Vertical">
|
||||
<Image
|
||||
Source="/Resources/Icons-png/geo-icons/centered-circle.png"
|
||||
Source="{DynamicResource GeoIconCircle}"
|
||||
RenderOptions.BitmapScalingMode="HighQuality"
|
||||
Margin="0,4,0,2" Height="19" Width="19" />
|
||||
<Label Content="中心圆" FontSize="8" HorizontalAlignment="Center" />
|
||||
@@ -8626,7 +8789,7 @@
|
||||
Margin="0,0,0,0" Height="38" Width="32"
|
||||
Orientation="Vertical">
|
||||
<Image
|
||||
Source="/Resources/Icons-png/geo-icons/centered-circle-dashed.png"
|
||||
Source="{DynamicResource GeoIconDashedCircle}"
|
||||
RenderOptions.BitmapScalingMode="HighQuality"
|
||||
Margin="0,4,0,2"
|
||||
Height="19" Width="19" />
|
||||
@@ -8636,7 +8799,7 @@
|
||||
Margin="0,0,0,0" Height="38" Width="32"
|
||||
Orientation="Vertical">
|
||||
<Image
|
||||
Source="/Resources/Icons-png/geo-icons/centered-oval.png"
|
||||
Source="{DynamicResource GeoIconEllipseCenter}"
|
||||
RenderOptions.BitmapScalingMode="HighQuality"
|
||||
Margin="0,4,0,2" Height="19" Width="19" />
|
||||
<Label Content="中心椭圆" FontSize="8" HorizontalAlignment="Center" />
|
||||
@@ -8666,7 +8829,7 @@
|
||||
Margin="4,0,4,6">
|
||||
<ui:SimpleStackPanel MouseUp="BtnDrawCuboid_Click" Margin="0,0,0,0"
|
||||
Height="38" Width="32" Orientation="Vertical">
|
||||
<Image Source="/Resources/Icons-png/geo-icons/cube.png"
|
||||
<Image Source="{DynamicResource GeoIconCuboid}"
|
||||
RenderOptions.BitmapScalingMode="HighQuality"
|
||||
Margin="0,4,0,2" Height="19" Width="19" />
|
||||
<Label Content="长方体" FontSize="8" HorizontalAlignment="Center" />
|
||||
@@ -8674,7 +8837,7 @@
|
||||
<ui:SimpleStackPanel MouseUp="BtnDrawRectangle_Click"
|
||||
Margin="0,0,0,0"
|
||||
Height="38" Width="32" Orientation="Vertical">
|
||||
<Image Source="/Resources/Icons-png/geo-icons/square.png"
|
||||
<Image Source="{DynamicResource GeoIconRectangle}"
|
||||
RenderOptions.BitmapScalingMode="HighQuality"
|
||||
Margin="0,4,0,2" Height="19" Width="19" />
|
||||
<Label Content="正方形" FontSize="8" HorizontalAlignment="Center" />
|
||||
@@ -8682,14 +8845,14 @@
|
||||
<ui:SimpleStackPanel MouseUp="BtnDrawCylinder_Click"
|
||||
Margin="0,0,0,0"
|
||||
Height="38" Width="32" Orientation="Vertical">
|
||||
<Image Source="/Resources/Icons-png/geo-icons/cylinder.png"
|
||||
<Image Source="{DynamicResource GeoIconCylinder}"
|
||||
RenderOptions.BitmapScalingMode="HighQuality"
|
||||
Margin="0,4,0,2" Height="19" Width="19" />
|
||||
<Label Content="画圆柱" FontSize="8" HorizontalAlignment="Center" />
|
||||
</ui:SimpleStackPanel>
|
||||
<ui:SimpleStackPanel MouseUp="BtnDrawCone_Click" Margin="0,0,0,0"
|
||||
Height="38" Width="32" Orientation="Vertical">
|
||||
<Image Source="/Resources/Icons-png/geo-icons/cone.png"
|
||||
<Image Source="{DynamicResource GeoIconCone}"
|
||||
RenderOptions.BitmapScalingMode="HighQuality"
|
||||
Margin="0,4,0,2" Height="19" Width="19" />
|
||||
<Label Content="画圆锥" FontSize="8" HorizontalAlignment="Center" />
|
||||
@@ -8898,14 +9061,14 @@
|
||||
<ui:SimpleStackPanel Orientation="Horizontal" HorizontalAlignment="Center"
|
||||
Margin="0,0,0,0" Spacing="4">
|
||||
<Border x:Name="CircleEraserTabButton" MouseDown="SwitchToCircleEraser"
|
||||
Background="#553b82f6" Height="20" Width="40" CornerRadius="3">
|
||||
Background="{DynamicResource FloatBarButtonBackgroundPointerOverKey}" Height="20" Width="40" CornerRadius="3">
|
||||
<Canvas>
|
||||
<ui:SimpleStackPanel x:Name="CircleEraserTabButtonIndicator"
|
||||
Visibility="Visible"
|
||||
Orientation="Horizontal"
|
||||
Canvas.Left="11" Canvas.Right="11"
|
||||
Canvas.Bottom="0">
|
||||
<Border Width="18" Height="2" Background="#2563eb"
|
||||
<Border Width="18" Height="2" Background="{DynamicResource FloatBarButtonButtonBackgroundPressedKey}"
|
||||
CornerRadius="1" />
|
||||
</ui:SimpleStackPanel>
|
||||
<ui:SimpleStackPanel Orientation="Vertical" Height="20"
|
||||
@@ -8914,10 +9077,9 @@
|
||||
Orientation="Horizontal"
|
||||
HorizontalAlignment="Center" Margin="0,3">
|
||||
<TextBlock x:Name="CircleEraserTabButtonText"
|
||||
Foreground="#172554" FontWeight="Medium"
|
||||
Foreground="{DynamicResource FloatBarForeground}" FontWeight="Medium"
|
||||
FontSize="9" TextAlignment="Center"
|
||||
Text="圆形擦"
|
||||
Margin="2,1,0,0" />
|
||||
Text="圆形擦" />
|
||||
</ui:SimpleStackPanel>
|
||||
</ui:SimpleStackPanel>
|
||||
</Canvas>
|
||||
@@ -8930,7 +9092,7 @@
|
||||
x:Name="RectangleEraserTabButtonIndicator"
|
||||
Orientation="Horizontal" Canvas.Left="11"
|
||||
Canvas.Right="11" Canvas.Bottom="0">
|
||||
<Border Width="18" Height="2" Background="#2563eb"
|
||||
<Border Width="18" Height="2" Background="{DynamicResource FloatBarButtonButtonBackgroundPressedKey}"
|
||||
CornerRadius="1" />
|
||||
</ui:SimpleStackPanel>
|
||||
<ui:SimpleStackPanel Orientation="Vertical" Height="20"
|
||||
@@ -8939,10 +9101,9 @@
|
||||
Orientation="Horizontal"
|
||||
HorizontalAlignment="Center" Margin="0,3">
|
||||
<TextBlock x:Name="RectangleEraserTabButtonText"
|
||||
Foreground="#172554" FontWeight="Medium"
|
||||
Foreground="{DynamicResource FloatBarForeground}" FontWeight="Medium"
|
||||
FontSize="9" TextAlignment="Center"
|
||||
Text="黑板擦"
|
||||
Margin="2,1,0,0" />
|
||||
Text="黑板擦" />
|
||||
</ui:SimpleStackPanel>
|
||||
</ui:SimpleStackPanel>
|
||||
</Canvas>
|
||||
@@ -9291,7 +9452,7 @@
|
||||
|
||||
MouseUp="TwoFingerGestureBorder_MouseUp" Background="Transparent"
|
||||
Orientation="Vertical" HorizontalAlignment="Center" Width="36" Margin="0">
|
||||
<Image x:Name="EnableTwoFingerGestureBtn" Source="/Resources/new-icons/gesture.png"
|
||||
<Image x:Name="EnableTwoFingerGestureBtn" Source="{DynamicResource GestureIcon}"
|
||||
RenderOptions.BitmapScalingMode="HighQuality" Width="28" Height="18"
|
||||
Margin="0,3,0,0" />
|
||||
<TextBlock x:Name="gestureiconText" Text="手势" Foreground="{DynamicResource FloatBarForeground}" FontSize="8"
|
||||
@@ -9320,7 +9481,7 @@
|
||||
</Border>
|
||||
<ui:SimpleStackPanel Orientation="Horizontal" Spacing="4" VerticalAlignment="Center"
|
||||
HorizontalAlignment="Center" Margin="0,3,0,0">
|
||||
<Image Source="/Resources/new-icons/multi-touch.png"
|
||||
<Image Source="{DynamicResource MultiTouchIcon}"
|
||||
RenderOptions.BitmapScalingMode="HighQuality" Height="16" Width="16" />
|
||||
<Label Content="多指书写" FontSize="10" VerticalAlignment="Center" />
|
||||
<Viewbox Width="36" Height="18" Margin="4,0,0,0">
|
||||
@@ -9344,7 +9505,7 @@
|
||||
<ui:SimpleStackPanel Opacity="1" x:Name="TwoFingerGestureSimpleStackPanel"
|
||||
Orientation="Horizontal" Spacing="4" VerticalAlignment="Center"
|
||||
HorizontalAlignment="Center">
|
||||
<Image Source="/Resources/new-icons/hand-move.png"
|
||||
<Image Source="{DynamicResource HandMoveIcon}"
|
||||
RenderOptions.BitmapScalingMode="HighQuality" Height="16" Width="16" />
|
||||
<Label Content="双指移动" FontSize="10" VerticalAlignment="Center" />
|
||||
<Viewbox Width="36" Height="18" Margin="4,0,0,0">
|
||||
@@ -9369,7 +9530,7 @@
|
||||
Opacity="{Binding ElementName=TwoFingerGestureSimpleStackPanel, Path=Opacity}"
|
||||
Orientation="Horizontal" Spacing="4" VerticalAlignment="Center"
|
||||
HorizontalAlignment="Center">
|
||||
<Image Source="/Resources/new-icons/zoom.png"
|
||||
<Image Source="{DynamicResource ZoomIcon}"
|
||||
RenderOptions.BitmapScalingMode="HighQuality" Height="16" Width="16" />
|
||||
<Label Content="双指缩放" FontSize="10" VerticalAlignment="Center" />
|
||||
<Viewbox Width="36" Height="18" Margin="4,0,0,0">
|
||||
@@ -9394,7 +9555,7 @@
|
||||
Opacity="{Binding ElementName=TwoFingerGestureSimpleStackPanel, Path=Opacity}"
|
||||
Orientation="Horizontal" Spacing="4" VerticalAlignment="Center"
|
||||
HorizontalAlignment="Center">
|
||||
<Image Source="/Resources/new-icons/rotate.png"
|
||||
<Image Source="{DynamicResource RotateIcon}"
|
||||
RenderOptions.BitmapScalingMode="HighQuality" Height="16" Width="16" />
|
||||
<Label Content="双指旋转" FontSize="10" VerticalAlignment="Center" />
|
||||
<Viewbox Width="36" Height="18" Margin="4,0,0,0">
|
||||
@@ -9428,7 +9589,7 @@
|
||||
<ui:SimpleStackPanel Background="Transparent" Orientation="Vertical"
|
||||
HorizontalAlignment="Center"
|
||||
Width="28" Margin="0,0">
|
||||
<Image Source="/Resources/new-icons/end-slides-show.png"
|
||||
<Image Source="{DynamicResource QuickPanelEndSlideshowIcon}"
|
||||
RenderOptions.BitmapScalingMode="HighQuality" Width="28" Height="17"
|
||||
Margin="0,3,0,0" />
|
||||
<TextBlock Text="退出" Foreground="{DynamicResource FloatBarForeground}" FontSize="8" Margin="0,1,0,0"
|
||||
@@ -9771,3 +9932,4 @@
|
||||
</Viewbox>
|
||||
</Grid>
|
||||
</Window>
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Principal;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
@@ -38,6 +39,12 @@ namespace Ink_Canvas
|
||||
{
|
||||
public partial class MainWindow : Window
|
||||
{
|
||||
[DllImport("UIAccessDLL_x86.dll", EntryPoint = "PrepareUIAccess", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern Int32 PrepareUIAccessX86();
|
||||
|
||||
[DllImport("UIAccessDLL_x64.dll", EntryPoint = "PrepareUIAccess", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern Int32 PrepareUIAccessX64();
|
||||
|
||||
// 每一页一个Canvas对象
|
||||
private List<System.Windows.Controls.Canvas> whiteboardPages = new List<System.Windows.Controls.Canvas>();
|
||||
private int currentPageIndex;
|
||||
@@ -53,8 +60,12 @@ namespace Ink_Canvas
|
||||
// 悬浮窗拦截管理器
|
||||
private FloatingWindowInterceptorManager _floatingWindowInterceptorManager;
|
||||
|
||||
// 快抽悬浮按钮
|
||||
private QuickDrawFloatingButton _quickDrawFloatingButton;
|
||||
|
||||
// 设置面板相关状态
|
||||
private bool userChangedNoFocusModeInSettings;
|
||||
private bool isTemporarilyDisablingNoFocusMode = false;
|
||||
|
||||
|
||||
|
||||
@@ -391,7 +402,7 @@ namespace Ink_Canvas
|
||||
//加载设置
|
||||
LoadSettings(true);
|
||||
AutoBackupManager.Initialize(Settings);
|
||||
|
||||
|
||||
// 检查保存路径是否可用,不可用则修正
|
||||
try
|
||||
{
|
||||
@@ -486,7 +497,6 @@ namespace Ink_Canvas
|
||||
LogHelper.WriteLogToFile("Ink Canvas Loaded", LogHelper.LogType.Event);
|
||||
|
||||
isLoaded = true;
|
||||
|
||||
BlackBoardLeftSidePageListView.ItemsSource = blackBoardSidePageListViewObservableCollection;
|
||||
BlackBoardRightSidePageListView.ItemsSource = blackBoardSidePageListViewObservableCollection;
|
||||
|
||||
@@ -523,6 +533,9 @@ namespace Ink_Canvas
|
||||
else
|
||||
RadioCrashNoAction.IsChecked = true;
|
||||
|
||||
// 显示快抽悬浮按钮
|
||||
ShowQuickDrawFloatingButton();
|
||||
|
||||
// 如果当前不是黑板模式,则切换到黑板模式
|
||||
if (currentMode == 0)
|
||||
{
|
||||
@@ -550,7 +563,13 @@ namespace Ink_Canvas
|
||||
ApplyNoFocusMode();
|
||||
ToggleSwitchAlwaysOnTop.IsOn = Settings.Advanced.IsAlwaysOnTop;
|
||||
ApplyAlwaysOnTop();
|
||||
|
||||
// 初始化UIA置顶开关
|
||||
ToggleSwitchUIAccessTopMost.IsOn = Settings.Advanced.EnableUIAccessTopMost;
|
||||
UpdateUIAccessTopMostVisibility();
|
||||
|
||||
App.IsUIAccessTopMostEnabled = Settings.Advanced.EnableUIAccessTopMost;
|
||||
|
||||
// 初始化剪贴板监控
|
||||
InitializeClipboardMonitoring();
|
||||
|
||||
@@ -655,6 +674,19 @@ namespace Ink_Canvas
|
||||
private void Window_Closing(object sender, CancelEventArgs e)
|
||||
{
|
||||
LogHelper.WriteLogToFile("Ink Canvas closing", LogHelper.LogType.Event);
|
||||
try
|
||||
{
|
||||
if (_quickDrawFloatingButton != null)
|
||||
{
|
||||
_quickDrawFloatingButton.Close();
|
||||
_quickDrawFloatingButton = null;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogHelper.WriteLogToFile($"关闭快抽悬浮按钮时出错: {ex.Message}", LogHelper.LogType.Error);
|
||||
}
|
||||
|
||||
if (!CloseIsFromButton && Settings.Advanced.IsSecondConfirmWhenShutdownApp)
|
||||
{
|
||||
// 第一个确认对话框
|
||||
@@ -788,7 +820,7 @@ namespace Ink_Canvas
|
||||
}
|
||||
}
|
||||
|
||||
// 辅助方法:使用多线路组下载更新
|
||||
// 使用多线路组下载更新
|
||||
private async Task<bool> DownloadUpdateWithFallback(string version, AutoUpdateHelper.UpdateLineGroup primaryGroup, UpdateChannel channel)
|
||||
{
|
||||
try
|
||||
@@ -833,8 +865,14 @@ namespace Ink_Canvas
|
||||
// 声明下载状态变量,用于整个方法
|
||||
bool isDownloadSuccessful = false;
|
||||
|
||||
bool hasValidLineGroup = lineGroup != null;
|
||||
|
||||
if (AvailableLatestVersion != null)
|
||||
{
|
||||
// 检测到新版本,停止重试定时器
|
||||
timerCheckAutoUpdateRetry.Stop();
|
||||
updateCheckRetryCount = 0;
|
||||
|
||||
// 检测到新版本
|
||||
LogHelper.WriteLogToFile($"AutoUpdate | New version available: {AvailableLatestVersion}");
|
||||
|
||||
@@ -998,8 +1036,26 @@ namespace Ink_Canvas
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (hasValidLineGroup)
|
||||
{
|
||||
LogHelper.WriteLogToFile("AutoUpdate | Current version is already the latest, no retry needed");
|
||||
|
||||
// 停止重试定时器
|
||||
timerCheckAutoUpdateRetry.Stop();
|
||||
updateCheckRetryCount = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 检查更新失败,启动重试定时器
|
||||
LogHelper.WriteLogToFile("AutoUpdate | Update check failed, starting retry timer");
|
||||
|
||||
// 重置重试计数
|
||||
updateCheckRetryCount = 0;
|
||||
|
||||
// 启动重试定时器,10分钟后重新检查
|
||||
timerCheckAutoUpdateRetry.Start();
|
||||
|
||||
// 清理更新文件夹
|
||||
AutoUpdateHelper.DeleteUpdatesFolder();
|
||||
}
|
||||
}
|
||||
@@ -1181,14 +1237,14 @@ namespace Ink_Canvas
|
||||
RefreshDeviceInfo();
|
||||
}
|
||||
|
||||
// 新增:个性化设置
|
||||
// 个性化设置
|
||||
private void NavTheme_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
// 切换到个性化设置页面
|
||||
ShowSettingsSection("theme");
|
||||
}
|
||||
|
||||
// 新增:快捷键设置
|
||||
// 快捷键设置
|
||||
private void NavShortcuts_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
OpenHotkeySettingsWindow();
|
||||
@@ -1285,7 +1341,7 @@ namespace Ink_Canvas
|
||||
}
|
||||
}
|
||||
|
||||
// 新增:折叠侧边栏
|
||||
// 折叠侧边栏
|
||||
private void CollapseNavSidebar_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
// 折叠/展开侧边栏
|
||||
@@ -1302,7 +1358,7 @@ namespace Ink_Canvas
|
||||
}
|
||||
}
|
||||
|
||||
// 新增:显示侧边栏
|
||||
// 显示侧边栏
|
||||
private void ShowNavSidebar_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
// 确保侧边栏展开
|
||||
@@ -1310,7 +1366,7 @@ namespace Ink_Canvas
|
||||
columnDefinitions[0].Width = new GridLength(50);
|
||||
}
|
||||
|
||||
// 辅助方法:显示指定的设置部分
|
||||
// 显示指定的设置部分
|
||||
private async void ShowSettingsSection(string sectionTag)
|
||||
{
|
||||
// 显示设置面板
|
||||
@@ -1797,13 +1853,18 @@ namespace Ink_Canvas
|
||||
|
||||
// 添加定时器来维护置顶状态
|
||||
private DispatcherTimer topmostMaintenanceTimer;
|
||||
private DispatcherTimer autoSaveStrokesTimer;
|
||||
private bool isTopmostMaintenanceEnabled;
|
||||
|
||||
private void ApplyNoFocusMode()
|
||||
{
|
||||
var hwnd = new WindowInteropHelper(this).Handle;
|
||||
int exStyle = GetWindowLong(hwnd, GWL_EXSTYLE);
|
||||
if (Settings.Advanced.IsNoFocusMode)
|
||||
|
||||
bool shouldBeNoFocus = isTemporarilyDisablingNoFocusMode ?
|
||||
false : Settings.Advanced.IsNoFocusMode;
|
||||
|
||||
if (shouldBeNoFocus)
|
||||
{
|
||||
SetWindowLong(hwnd, GWL_EXSTYLE, exStyle | WS_EX_NOACTIVATE);
|
||||
}
|
||||
@@ -1820,10 +1881,8 @@ namespace Ink_Canvas
|
||||
var hwnd = new WindowInteropHelper(this).Handle;
|
||||
if (Settings.Advanced.IsAlwaysOnTop)
|
||||
{
|
||||
// 先设置WPF的Topmost属性
|
||||
Topmost = true;
|
||||
|
||||
// 使用更强的Win32 API调用来确保置顶
|
||||
// 1. 设置窗口样式为置顶
|
||||
int exStyle = GetWindowLong(hwnd, GWL_EXSTYLE);
|
||||
SetWindowLong(hwnd, GWL_EXSTYLE, exStyle | WS_EX_TOPMOST);
|
||||
@@ -1832,8 +1891,8 @@ namespace Ink_Canvas
|
||||
SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0,
|
||||
SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_SHOWWINDOW | SWP_NOOWNERZORDER);
|
||||
|
||||
// 3. 如果启用了无焦点模式,需要特殊处理
|
||||
if (Settings.Advanced.IsNoFocusMode)
|
||||
// 3. 如果启用了无焦点模式且未启用UIA置顶,需要特殊处理
|
||||
if (Settings.Advanced.IsNoFocusMode && !Settings.Advanced.EnableUIAccessTopMost)
|
||||
{
|
||||
// 启动置顶维护定时器
|
||||
StartTopmostMaintenance();
|
||||
@@ -1857,11 +1916,6 @@ namespace Ink_Canvas
|
||||
|
||||
// 3. 停止置顶维护定时器
|
||||
StopTopmostMaintenance();
|
||||
|
||||
// 注意:这里不直接设置Topmost,让其他代码根据模式决定
|
||||
|
||||
// 添加调试日志
|
||||
LogHelper.WriteLogToFile("应用窗口置顶: 取消置顶", LogHelper.LogType.Trace);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -1875,6 +1929,11 @@ namespace Ink_Canvas
|
||||
/// </summary>
|
||||
private void StartTopmostMaintenance()
|
||||
{
|
||||
if (Settings.Advanced.EnableUIAccessTopMost)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (isTopmostMaintenanceEnabled) return;
|
||||
|
||||
if (topmostMaintenanceTimer == null)
|
||||
@@ -1909,6 +1968,12 @@ namespace Ink_Canvas
|
||||
{
|
||||
try
|
||||
{
|
||||
if (Settings.Advanced.EnableUIAccessTopMost)
|
||||
{
|
||||
StopTopmostMaintenance();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Settings.Advanced.IsAlwaysOnTop || !Settings.Advanced.IsNoFocusMode)
|
||||
{
|
||||
StopTopmostMaintenance();
|
||||
@@ -1985,6 +2050,12 @@ namespace Ink_Canvas
|
||||
var toggle = sender as ToggleSwitch;
|
||||
Settings.Advanced.IsNoFocusMode = toggle != null && toggle.IsOn;
|
||||
SaveSettingsToFile();
|
||||
|
||||
if (isTemporarilyDisablingNoFocusMode)
|
||||
{
|
||||
isTemporarilyDisablingNoFocusMode = false;
|
||||
}
|
||||
|
||||
ApplyNoFocusMode();
|
||||
|
||||
// 如果启用了窗口置顶,需要重新应用置顶设置以处理无焦点模式的变化
|
||||
@@ -2007,6 +2078,21 @@ namespace Ink_Canvas
|
||||
Settings.Advanced.IsAlwaysOnTop = toggle != null && toggle.IsOn;
|
||||
SaveSettingsToFile();
|
||||
ApplyAlwaysOnTop();
|
||||
UpdateUIAccessTopMostVisibility();
|
||||
}
|
||||
|
||||
private void ToggleSwitchUIAccessTopMost_Toggled(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (!isLoaded) return;
|
||||
var toggle = sender as ToggleSwitch;
|
||||
bool newValue = toggle != null && toggle.IsOn;
|
||||
|
||||
Settings.Advanced.EnableUIAccessTopMost = newValue;
|
||||
SaveSettingsToFile();
|
||||
ApplyUIAccessTopMost();
|
||||
|
||||
App.IsUIAccessTopMostEnabled = newValue;
|
||||
|
||||
}
|
||||
|
||||
private void Window_Activated(object sender, EventArgs e)
|
||||
@@ -2436,12 +2522,16 @@ namespace Ink_Canvas
|
||||
SideControlMinimumAutomationSlider,
|
||||
RandWindowOnceCloseLatencySlider,
|
||||
RandWindowOnceMaxStudentsSlider,
|
||||
TimerVolumeSlider,
|
||||
ProgressiveReminderVolumeSlider,
|
||||
BoardInkWidthSlider,
|
||||
BoardInkAlphaSlider,
|
||||
BoardHighlighterWidthSlider,
|
||||
InkWidthSlider,
|
||||
InkAlphaSlider,
|
||||
HighlighterWidthSlider
|
||||
HighlighterWidthSlider,
|
||||
MLAvoidanceHistorySlider,
|
||||
MLAvoidanceWeightSlider
|
||||
};
|
||||
|
||||
foreach (var slider in sliders)
|
||||
@@ -2697,7 +2787,7 @@ namespace Ink_Canvas
|
||||
if (toggle != null)
|
||||
{
|
||||
Settings.ModeSettings.IsPPTOnlyMode = toggle.IsOn;
|
||||
|
||||
|
||||
// 保存设置到文件
|
||||
SaveSettingsToFile();
|
||||
|
||||
@@ -2789,20 +2879,20 @@ namespace Ink_Canvas
|
||||
private void ComboBoxTheme_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
if (!isLoaded) return;
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
System.Windows.Controls.ComboBox comboBox = sender as System.Windows.Controls.ComboBox;
|
||||
if (comboBox != null)
|
||||
{
|
||||
Settings.Appearance.Theme = comboBox.SelectedIndex;
|
||||
|
||||
|
||||
// 应用新主题
|
||||
ApplyTheme(comboBox.SelectedIndex);
|
||||
|
||||
|
||||
// 保存设置
|
||||
SaveSettingsToFile();
|
||||
|
||||
|
||||
// 显示通知
|
||||
string themeName;
|
||||
switch (comboBox.SelectedIndex)
|
||||
@@ -2820,7 +2910,7 @@ namespace Ink_Canvas
|
||||
themeName = "未知主题";
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
ShowNotification($"已切换到{themeName}");
|
||||
}
|
||||
}
|
||||
@@ -2842,29 +2932,29 @@ namespace Ink_Canvas
|
||||
switch (themeIndex)
|
||||
{
|
||||
case 0: // 浅色主题
|
||||
SetTheme("Light");
|
||||
SetTheme("Light", true);
|
||||
// 浅色主题下设置浮动栏为完全不透明
|
||||
ViewboxFloatingBar.Opacity = 1.0;
|
||||
break;
|
||||
case 1: // 深色主题
|
||||
SetTheme("Dark");
|
||||
SetTheme("Dark", true);
|
||||
// 深色主题下设置浮动栏为完全不透明
|
||||
ViewboxFloatingBar.Opacity = 1.0;
|
||||
break;
|
||||
case 2: // 跟随系统
|
||||
if (IsSystemThemeLight())
|
||||
{
|
||||
SetTheme("Light");
|
||||
SetTheme("Light", true);
|
||||
ViewboxFloatingBar.Opacity = 1.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
SetTheme("Dark");
|
||||
SetTheme("Dark", true);
|
||||
ViewboxFloatingBar.Opacity = 1.0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
// 强制刷新通知框的颜色资源
|
||||
RefreshNotificationColors();
|
||||
}
|
||||
@@ -2873,7 +2963,7 @@ namespace Ink_Canvas
|
||||
LogHelper.WriteLogToFile($"应用主题时出错: {ex.Message}", LogHelper.LogType.Error);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 刷新通知框的颜色资源
|
||||
/// </summary>
|
||||
@@ -2888,7 +2978,7 @@ namespace Ink_Canvas
|
||||
border.Background = (Brush)Application.Current.FindResource("SettingsPageBackground");
|
||||
border.BorderBrush = new SolidColorBrush(Color.FromRgb(185, 28, 28)); // 保持红色边框
|
||||
}
|
||||
|
||||
|
||||
TextBlockNotice.Foreground = (Brush)Application.Current.FindResource("SettingsPageForeground");
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -2897,6 +2987,133 @@ namespace Ink_Canvas
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region UIA置顶功能
|
||||
|
||||
/// <summary>
|
||||
/// 更新UIA置顶开关的可见性
|
||||
/// </summary>
|
||||
private void UpdateUIAccessTopMostVisibility()
|
||||
{
|
||||
try
|
||||
{
|
||||
var visibility = Settings.Advanced.IsAlwaysOnTop ? Visibility.Visible : Visibility.Collapsed;
|
||||
|
||||
if (UIAccessTopMostPanel != null)
|
||||
{
|
||||
UIAccessTopMostPanel.Visibility = visibility;
|
||||
}
|
||||
|
||||
if (UIAccessTopMostDescription != null)
|
||||
{
|
||||
UIAccessTopMostDescription.Visibility = visibility;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogHelper.WriteLogToFile($"更新UIA置顶开关可见性时出错: {ex.Message}", LogHelper.LogType.Error);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 应用UIA置顶功能
|
||||
/// </summary>
|
||||
private void ApplyUIAccessTopMost()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (Settings.Advanced.EnableUIAccessTopMost && Settings.Advanced.IsAlwaysOnTop)
|
||||
{
|
||||
// 检查是否以管理员权限运行
|
||||
var identity = WindowsIdentity.GetCurrent();
|
||||
var principal = new WindowsPrincipal(identity);
|
||||
|
||||
if (principal.IsInRole(WindowsBuiltInRole.Administrator))
|
||||
{
|
||||
try
|
||||
{
|
||||
timerKillProcess.Stop();
|
||||
if (App.watchdogProcess != null && !App.watchdogProcess.HasExited)
|
||||
{
|
||||
App.watchdogProcess.Kill();
|
||||
App.watchdogProcess = null;
|
||||
}
|
||||
|
||||
|
||||
// 调用UIAccess DLL
|
||||
if (Environment.Is64BitProcess)
|
||||
{
|
||||
PrepareUIAccessX64();
|
||||
}
|
||||
else
|
||||
{
|
||||
PrepareUIAccessX86();
|
||||
}
|
||||
|
||||
App.StartWatchdogIfNeeded();
|
||||
timerKillProcess.Start();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogHelper.WriteLogToFile($"启用UIA置顶功能时出错: {ex.Message}", LogHelper.LogType.Error);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LogHelper.WriteLogToFile("UIA置顶功能需要管理员权限", LogHelper.LogType.Warning);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LogHelper.WriteLogToFile("UIA置顶功能已禁用", LogHelper.LogType.Trace);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogHelper.WriteLogToFile($"应用UIA置顶功能时出错: {ex.Message}", LogHelper.LogType.Error);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 显示快抽悬浮按钮
|
||||
/// </summary>
|
||||
private void ShowQuickDrawFloatingButton()
|
||||
{
|
||||
try
|
||||
{
|
||||
// 检查设置是否启用快抽功能
|
||||
if (Settings?.RandSettings?.EnableQuickDraw != true)
|
||||
{
|
||||
// 如果设置未启用,确保悬浮按钮被关闭
|
||||
if (_quickDrawFloatingButton != null)
|
||||
{
|
||||
_quickDrawFloatingButton.Close();
|
||||
_quickDrawFloatingButton = null;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// 如果已经存在悬浮按钮,先关闭它
|
||||
if (_quickDrawFloatingButton != null)
|
||||
{
|
||||
_quickDrawFloatingButton.Close();
|
||||
_quickDrawFloatingButton = null;
|
||||
}
|
||||
|
||||
// 创建并显示悬浮按钮
|
||||
_quickDrawFloatingButton = new QuickDrawFloatingButton();
|
||||
_quickDrawFloatingButton.Show();
|
||||
|
||||
LogHelper.WriteLogToFile("快抽悬浮按钮已显示", LogHelper.LogType.Trace);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogHelper.WriteLogToFile($"显示快抽悬浮按钮失败: {ex.Message}", LogHelper.LogType.Error);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,7 +103,6 @@ namespace Ink_Canvas
|
||||
HideSubPanels("cursor");
|
||||
SidePannelMarginAnimation(-10);
|
||||
});
|
||||
isFloatingBarChangingHideMode = false;
|
||||
}
|
||||
|
||||
private async void LeftUnFoldButtonDisplayQuickPanel_MouseUp(object sender, MouseButtonEventArgs e)
|
||||
@@ -325,7 +324,6 @@ namespace Ink_Canvas
|
||||
}
|
||||
});
|
||||
|
||||
isFloatingBarChangingHideMode = false;
|
||||
}
|
||||
|
||||
private async void SidePannelMarginAnimation(int MarginFromEdge, bool isNoAnimation = false) // Possible value: -50, -10
|
||||
|
||||
@@ -3,8 +3,10 @@ using Microsoft.Win32;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Media;
|
||||
using Application = System.Windows.Application;
|
||||
using ui = iNKORE.UI.WPF.Modern.Controls;
|
||||
|
||||
namespace Ink_Canvas
|
||||
{
|
||||
@@ -12,20 +14,20 @@ namespace Ink_Canvas
|
||||
{
|
||||
private Color FloatBarForegroundColor;
|
||||
|
||||
private void SetTheme(string theme)
|
||||
private void SetTheme(string theme, bool autoSwitchIcon = false)
|
||||
{
|
||||
// 清理现有的主题资源
|
||||
var resourcesToRemove = new List<ResourceDictionary>();
|
||||
foreach (var dict in Application.Current.Resources.MergedDictionaries)
|
||||
{
|
||||
if (dict.Source != null &&
|
||||
(dict.Source.ToString().Contains("Light.xaml") ||
|
||||
if (dict.Source != null &&
|
||||
(dict.Source.ToString().Contains("Light.xaml") ||
|
||||
dict.Source.ToString().Contains("Dark.xaml")))
|
||||
{
|
||||
resourcesToRemove.Add(dict);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
foreach (var dict in resourcesToRemove)
|
||||
{
|
||||
Application.Current.Resources.MergedDictionaries.Remove(dict);
|
||||
@@ -36,7 +38,7 @@ namespace Ink_Canvas
|
||||
var rd1 = new ResourceDictionary
|
||||
{ Source = new Uri("Resources/Styles/Light.xaml", UriKind.Relative) };
|
||||
Application.Current.Resources.MergedDictionaries.Add(rd1);
|
||||
|
||||
|
||||
// 在主题资源之后添加其他资源
|
||||
var rd2 = new ResourceDictionary
|
||||
{ Source = new Uri("Resources/DrawShapeImageDictionary.xaml", UriKind.Relative) };
|
||||
@@ -53,18 +55,37 @@ namespace Ink_Canvas
|
||||
ThemeManager.SetRequestedTheme(window, ElementTheme.Light);
|
||||
|
||||
InitializeFloatBarForegroundColor();
|
||||
|
||||
|
||||
// 刷新快速面板图标
|
||||
RefreshQuickPanelIcons();
|
||||
|
||||
|
||||
// 刷新墨迹选中栏图标
|
||||
RefreshStrokeSelectionIcons();
|
||||
|
||||
// 刷新图片选中栏图标
|
||||
RefreshImageSelectionIcons();
|
||||
|
||||
// 刷新手势按钮图标
|
||||
RefreshGestureButtonIcon();
|
||||
|
||||
RefreshFloatingBarHighlightColors();
|
||||
|
||||
if (autoSwitchIcon)
|
||||
{
|
||||
AutoSwitchFloatingBarIconForTheme("Light");
|
||||
}
|
||||
|
||||
// 强制刷新UI
|
||||
window.InvalidateVisual();
|
||||
|
||||
// 通知其他窗口刷新主题
|
||||
RefreshOtherWindowsTheme();
|
||||
}
|
||||
else if (theme == "Dark")
|
||||
{
|
||||
var rd1 = new ResourceDictionary { Source = new Uri("Resources/Styles/Dark.xaml", UriKind.Relative) };
|
||||
Application.Current.Resources.MergedDictionaries.Add(rd1);
|
||||
|
||||
|
||||
// 在主题资源之后添加其他资源
|
||||
var rd2 = new ResourceDictionary
|
||||
{ Source = new Uri("Resources/DrawShapeImageDictionary.xaml", UriKind.Relative) };
|
||||
@@ -81,12 +102,31 @@ namespace Ink_Canvas
|
||||
ThemeManager.SetRequestedTheme(window, ElementTheme.Dark);
|
||||
|
||||
InitializeFloatBarForegroundColor();
|
||||
|
||||
|
||||
// 刷新快速面板图标
|
||||
RefreshQuickPanelIcons();
|
||||
|
||||
|
||||
// 刷新墨迹选中栏图标
|
||||
RefreshStrokeSelectionIcons();
|
||||
|
||||
// 刷新图片选中栏图标
|
||||
RefreshImageSelectionIcons();
|
||||
|
||||
// 刷新手势按钮图标
|
||||
RefreshGestureButtonIcon();
|
||||
|
||||
RefreshFloatingBarHighlightColors();
|
||||
|
||||
if (autoSwitchIcon)
|
||||
{
|
||||
AutoSwitchFloatingBarIconForTheme("Dark");
|
||||
}
|
||||
|
||||
// 强制刷新UI
|
||||
window.InvalidateVisual();
|
||||
|
||||
// 通知其他窗口刷新主题
|
||||
RefreshOtherWindowsTheme();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,17 +138,17 @@ namespace Ink_Canvas
|
||||
try
|
||||
{
|
||||
FloatBarForegroundColor = (Color)Application.Current.FindResource("FloatBarForegroundColor");
|
||||
|
||||
|
||||
// 强制刷新浮动工具栏按钮颜色
|
||||
RefreshFloatingBarButtonColors();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// 如果无法从资源中加载,使用默认颜色
|
||||
FloatBarForegroundColor = Color.FromRgb(0, 0, 0);
|
||||
FloatBarForegroundColor = Color.FromRgb(0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 刷新快速面板图标
|
||||
/// </summary>
|
||||
@@ -138,6 +178,49 @@ namespace Ink_Canvas
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 刷新浮动栏高光条颜色
|
||||
/// </summary>
|
||||
private void RefreshFloatingBarHighlightColors()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (FloatingbarSelectionBG != null && FloatingbarSelectionBG.Visibility == Visibility.Visible)
|
||||
{
|
||||
// 根据主题设置高光颜色
|
||||
Color highlightBackgroundColor;
|
||||
Color highlightBarColor;
|
||||
bool isDarkTheme = Settings.Appearance.Theme == 1 ||
|
||||
(Settings.Appearance.Theme == 2 && !IsSystemThemeLight());
|
||||
|
||||
if (isDarkTheme)
|
||||
{
|
||||
highlightBackgroundColor = Color.FromArgb(21, 102, 204, 255);
|
||||
highlightBarColor = Color.FromRgb(102, 204, 255);
|
||||
}
|
||||
else
|
||||
{
|
||||
highlightBackgroundColor = Color.FromArgb(21, 59, 130, 246);
|
||||
highlightBarColor = Color.FromRgb(37, 99, 235);
|
||||
}
|
||||
|
||||
// 设置高光背景颜色
|
||||
FloatingbarSelectionBG.Background = new SolidColorBrush(highlightBackgroundColor);
|
||||
if (FloatingbarSelectionBG.Child is System.Windows.Controls.Canvas canvas && canvas.Children.Count > 0)
|
||||
{
|
||||
var firstChild = canvas.Children[0];
|
||||
if (firstChild is Border innerBorder)
|
||||
{
|
||||
innerBorder.Background = new SolidColorBrush(highlightBarColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 刷新浮动工具栏按钮颜色
|
||||
/// </summary>
|
||||
@@ -145,9 +228,20 @@ namespace Ink_Canvas
|
||||
{
|
||||
try
|
||||
{
|
||||
// 选中状态的颜色(蓝底)
|
||||
var selectedColor = Color.FromRgb(30, 58, 138);
|
||||
|
||||
// 根据主题选择高光颜色
|
||||
Color selectedColor;
|
||||
bool isDarkTheme = Settings.Appearance.Theme == 1 ||
|
||||
(Settings.Appearance.Theme == 2 && !IsSystemThemeLight());
|
||||
|
||||
if (isDarkTheme)
|
||||
{
|
||||
selectedColor = Color.FromRgb(102, 204, 255);
|
||||
}
|
||||
else
|
||||
{
|
||||
selectedColor = Color.FromRgb(30, 58, 138);
|
||||
}
|
||||
|
||||
// 根据当前模式设置按钮颜色
|
||||
switch (_currentToolMode)
|
||||
{
|
||||
@@ -235,5 +329,217 @@ namespace Ink_Canvas
|
||||
|
||||
return light;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据主题自动切换浮动栏图标
|
||||
/// </summary>
|
||||
private void AutoSwitchFloatingBarIconForTheme(string theme)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (theme == "Light")
|
||||
{
|
||||
Settings.Appearance.FloatingBarImg = 0;
|
||||
}
|
||||
else if (theme == "Dark")
|
||||
{
|
||||
Settings.Appearance.FloatingBarImg = 3;
|
||||
}
|
||||
|
||||
UpdateFloatingBarIcon();
|
||||
UpdateFloatingBarIconComboBox();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新设置界面中的浮动栏图标选择下拉框显示
|
||||
/// </summary>
|
||||
private void UpdateFloatingBarIconComboBox()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (ComboBoxFloatingBarImg != null)
|
||||
{
|
||||
ComboBoxFloatingBarImg.SelectedIndex = Settings.Appearance.FloatingBarImg;
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 刷新墨迹选中栏图标
|
||||
/// </summary>
|
||||
private void RefreshStrokeSelectionIcons()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (BorderStrokeSelectionControl != null)
|
||||
{
|
||||
// 强制刷新墨迹选中栏的视觉状态
|
||||
BorderStrokeSelectionControl.InvalidateVisual();
|
||||
|
||||
// 刷新墨迹选中栏内的所有图标
|
||||
var viewbox = BorderStrokeSelectionControl.Child as Viewbox;
|
||||
if (viewbox?.Child is ui.SimpleStackPanel stackPanel)
|
||||
{
|
||||
RefreshStrokeSelectionIconsRecursive(stackPanel);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// 忽略异常,确保主题切换不会因为图标刷新失败而中断
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 递归刷新墨迹选中栏内的图标
|
||||
/// </summary>
|
||||
private void RefreshStrokeSelectionIconsRecursive(System.Windows.Controls.Panel panel)
|
||||
{
|
||||
try
|
||||
{
|
||||
foreach (var child in panel.Children)
|
||||
{
|
||||
if (child is Image image)
|
||||
{
|
||||
// 强制刷新图像
|
||||
image.InvalidateVisual();
|
||||
}
|
||||
else if (child is System.Windows.Controls.Panel childPanel)
|
||||
{
|
||||
// 递归处理子面板
|
||||
RefreshStrokeSelectionIconsRecursive(childPanel);
|
||||
}
|
||||
else if (child is Border border && border.Child is System.Windows.Controls.Panel borderPanel)
|
||||
{
|
||||
// 处理Border内的面板
|
||||
RefreshStrokeSelectionIconsRecursive(borderPanel);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// 忽略异常
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 刷新图片选中栏图标
|
||||
/// </summary>
|
||||
private void RefreshImageSelectionIcons()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (BorderImageSelectionControl != null)
|
||||
{
|
||||
// 强制刷新图片选中栏的视觉状态
|
||||
BorderImageSelectionControl.InvalidateVisual();
|
||||
|
||||
// 刷新图片选中栏内的所有图标
|
||||
var viewbox = BorderImageSelectionControl.Child as Viewbox;
|
||||
if (viewbox?.Child is ui.SimpleStackPanel stackPanel)
|
||||
{
|
||||
RefreshImageSelectionIconsRecursive(stackPanel);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// 忽略异常,确保主题切换不会因为图标刷新失败而中断
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 递归刷新图片选中栏内的图标
|
||||
/// </summary>
|
||||
private void RefreshImageSelectionIconsRecursive(System.Windows.Controls.Panel panel)
|
||||
{
|
||||
try
|
||||
{
|
||||
foreach (var child in panel.Children)
|
||||
{
|
||||
if (child is Image image)
|
||||
{
|
||||
// 强制刷新图像
|
||||
image.InvalidateVisual();
|
||||
}
|
||||
else if (child is System.Windows.Controls.Panel childPanel)
|
||||
{
|
||||
// 递归处理子面板
|
||||
RefreshImageSelectionIconsRecursive(childPanel);
|
||||
}
|
||||
else if (child is Border border && border.Child is System.Windows.Controls.Panel borderPanel)
|
||||
{
|
||||
// 处理Border内的面板
|
||||
RefreshImageSelectionIconsRecursive(borderPanel);
|
||||
}
|
||||
else if (child is Grid grid)
|
||||
{
|
||||
// 处理Grid内的子元素
|
||||
foreach (var gridChild in grid.Children)
|
||||
{
|
||||
if (gridChild is Image gridImage)
|
||||
{
|
||||
gridImage.InvalidateVisual();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// 忽略异常
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 刷新手势按钮图标
|
||||
/// </summary>
|
||||
private void RefreshGestureButtonIcon()
|
||||
{
|
||||
try
|
||||
{
|
||||
// 调用手势按钮颜色和图标更新方法,该方法会根据当前主题和手势状态设置正确的图标
|
||||
CheckEnableTwoFingerGestureBtnColorPrompt();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 刷新其他窗口的主题
|
||||
/// </summary>
|
||||
private void RefreshOtherWindowsTheme()
|
||||
{
|
||||
try
|
||||
{
|
||||
// 刷新所有打开的窗口
|
||||
foreach (Window window in Application.Current.Windows)
|
||||
{
|
||||
if (window is CountdownTimerWindow timerWindow)
|
||||
{
|
||||
timerWindow.RefreshTheme();
|
||||
}
|
||||
else if (window is RandWindow randWindow)
|
||||
{
|
||||
randWindow.RefreshTheme();
|
||||
}
|
||||
else if (window is OperatingGuideWindow operatingGuideWindow)
|
||||
{
|
||||
operatingGuideWindow.RefreshTheme();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
@@ -17,8 +18,8 @@ namespace Ink_Canvas
|
||||
private StrokeCollection lastTouchDownStrokeCollection = new StrokeCollection();
|
||||
private int CurrentWhiteboardIndex = 1;
|
||||
private int WhiteboardTotalCount = 1;
|
||||
private TimeMachineHistory[][] TimeMachineHistories = new TimeMachineHistory[101][];
|
||||
private bool[] savedMultiTouchModeStates = new bool[101];
|
||||
private TimeMachineHistory[][] TimeMachineHistories = new TimeMachineHistory[101][];
|
||||
private bool[] savedMultiTouchModeStates = new bool[101];
|
||||
|
||||
// 保存每页白板图片信息
|
||||
private void SaveStrokes(bool isBackupMain = false)
|
||||
@@ -120,15 +121,25 @@ namespace Ink_Canvas
|
||||
_currentCommitType = CommitReason.ClearingCanvas;
|
||||
if (isErasedByCode) _currentCommitType = CommitReason.CodeInput;
|
||||
|
||||
|
||||
|
||||
// 只清除笔画,不清除图片元素
|
||||
// 图片元素的清除由调用方决定
|
||||
inkCanvas.Strokes.Clear();
|
||||
|
||||
// 执行内存清理
|
||||
PerformLightweightMemoryCleanup();
|
||||
|
||||
_currentCommitType = CommitReason.UserInput;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 执行内存清理
|
||||
/// </summary>
|
||||
private void PerformLightweightMemoryCleanup()
|
||||
{
|
||||
Task.Run(() =>
|
||||
{
|
||||
GC.Collect();
|
||||
});
|
||||
}
|
||||
|
||||
// 恢复每页白板图片信息
|
||||
private void RestoreStrokes(bool isBackupMain = false)
|
||||
{
|
||||
@@ -197,20 +208,20 @@ namespace Ink_Canvas
|
||||
{
|
||||
// 恢复多指书写模式
|
||||
EnterMultiTouchModeIfNeeded();
|
||||
|
||||
|
||||
// 更新UI状态
|
||||
if (ToggleSwitchEnableMultiTouchMode != null)
|
||||
{
|
||||
ToggleSwitchEnableMultiTouchMode.IsOn = true;
|
||||
}
|
||||
|
||||
|
||||
LogHelper.WriteLogToFile($"恢复多指书写模式状态 - 页面索引: {pageIndex}", LogHelper.LogType.Info);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 确保多指书写模式关闭
|
||||
ExitMultiTouchModeIfNeeded();
|
||||
|
||||
|
||||
// 更新UI状态
|
||||
if (ToggleSwitchEnableMultiTouchMode != null)
|
||||
{
|
||||
@@ -413,13 +424,19 @@ namespace Ink_Canvas
|
||||
BtnLeftWhiteBoardSwitchNextLabel.Text = isLastPage ? "新页面" : "下一页";
|
||||
BtnRightWhiteBoardSwitchNextLabel.Text = isLastPage ? "新页面" : "下一页";
|
||||
|
||||
// 始终允许点击“下一页/新页面”按钮(除非已达最大页数)
|
||||
// 始终允许点击"下一页/新页面"按钮(除非已达最大页数)
|
||||
BtnWhiteBoardSwitchNext.IsEnabled = !isMaxPage;
|
||||
|
||||
// 保持按钮常亮(高亮)
|
||||
BtnLeftWhiteBoardSwitchNextGeometry.Brush = new SolidColorBrush(Color.FromArgb(255, 24, 24, 27));
|
||||
// 获取主题颜色资源
|
||||
var iconForegroundBrush = Application.Current.FindResource("IconForeground") as SolidColorBrush;
|
||||
|
||||
// 设置下一页按钮颜色
|
||||
if (iconForegroundBrush != null)
|
||||
{
|
||||
BtnLeftWhiteBoardSwitchNextGeometry.Brush = iconForegroundBrush;
|
||||
BtnRightWhiteBoardSwitchNextGeometry.Brush = iconForegroundBrush;
|
||||
}
|
||||
BtnLeftWhiteBoardSwitchNextLabel.Opacity = 1;
|
||||
BtnRightWhiteBoardSwitchNextGeometry.Brush = new SolidColorBrush(Color.FromArgb(255, 24, 24, 27));
|
||||
BtnRightWhiteBoardSwitchNextLabel.Opacity = 1;
|
||||
|
||||
BtnWhiteBoardSwitchPrevious.IsEnabled = true;
|
||||
@@ -427,16 +444,23 @@ namespace Ink_Canvas
|
||||
if (CurrentWhiteboardIndex == 1)
|
||||
{
|
||||
BtnWhiteBoardSwitchPrevious.IsEnabled = false;
|
||||
BtnLeftWhiteBoardSwitchPreviousGeometry.Brush = new SolidColorBrush(Color.FromArgb(127, 24, 24, 27));
|
||||
if (iconForegroundBrush != null)
|
||||
{
|
||||
var disabledBrush = new SolidColorBrush(Color.FromArgb(127, iconForegroundBrush.Color.R, iconForegroundBrush.Color.G, iconForegroundBrush.Color.B));
|
||||
BtnLeftWhiteBoardSwitchPreviousGeometry.Brush = disabledBrush;
|
||||
BtnRightWhiteBoardSwitchPreviousGeometry.Brush = disabledBrush;
|
||||
}
|
||||
BtnLeftWhiteBoardSwitchPreviousLabel.Opacity = 0.5;
|
||||
BtnRightWhiteBoardSwitchPreviousGeometry.Brush = new SolidColorBrush(Color.FromArgb(127, 24, 24, 27));
|
||||
BtnRightWhiteBoardSwitchPreviousLabel.Opacity = 0.5;
|
||||
}
|
||||
else
|
||||
{
|
||||
BtnLeftWhiteBoardSwitchPreviousGeometry.Brush = new SolidColorBrush(Color.FromArgb(255, 24, 24, 27));
|
||||
if (iconForegroundBrush != null)
|
||||
{
|
||||
BtnLeftWhiteBoardSwitchPreviousGeometry.Brush = iconForegroundBrush;
|
||||
BtnRightWhiteBoardSwitchPreviousGeometry.Brush = iconForegroundBrush;
|
||||
}
|
||||
BtnLeftWhiteBoardSwitchPreviousLabel.Opacity = 1;
|
||||
BtnRightWhiteBoardSwitchPreviousGeometry.Brush = new SolidColorBrush(Color.FromArgb(255, 24, 24, 27));
|
||||
BtnRightWhiteBoardSwitchPreviousLabel.Opacity = 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Ink_Canvas.Helpers;
|
||||
using Ink_Canvas.Helpers;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Windows;
|
||||
@@ -61,7 +61,7 @@ namespace Ink_Canvas
|
||||
ICCWaterMarkWhite.Visibility = Visibility.Collapsed;
|
||||
|
||||
// 设置为白板默认背景色
|
||||
Color defaultWhiteboardColor = Color.FromRgb(234, 235, 237);
|
||||
Color defaultWhiteboardColor = Color.FromRgb(255, 255, 255);
|
||||
|
||||
if (currentMode == 1) // 白板模式
|
||||
{
|
||||
@@ -135,7 +135,7 @@ namespace Ink_Canvas
|
||||
{
|
||||
Name = "BackgroundPalette",
|
||||
Visibility = Visibility.Collapsed,
|
||||
Background = new SolidColorBrush(Colors.White),
|
||||
Background = (SolidColorBrush)Application.Current.FindResource("SettingsPageBackground"),
|
||||
Opacity = 1,
|
||||
BorderBrush = new SolidColorBrush(Color.FromRgb(0x25, 0x63, 0xeb)),
|
||||
BorderThickness = new Thickness(1),
|
||||
@@ -166,7 +166,7 @@ namespace Ink_Canvas
|
||||
var titleText = new TextBlock
|
||||
{
|
||||
Text = "背景设置",
|
||||
Foreground = new SolidColorBrush(Colors.White),
|
||||
Foreground = (SolidColorBrush)Application.Current.FindResource("FloatBarForeground"),
|
||||
Padding = new Thickness(0, 5, 0, 0),
|
||||
FontSize = 11,
|
||||
FontWeight = FontWeights.Bold,
|
||||
@@ -198,7 +198,7 @@ namespace Ink_Canvas
|
||||
var modeTitle = new TextBlock
|
||||
{
|
||||
Text = "白板模式",
|
||||
Foreground = new SolidColorBrush(Color.FromRgb(0x17, 0x25, 0x54)),
|
||||
Foreground = (SolidColorBrush)Application.Current.FindResource("TextForeground"),
|
||||
FontSize = 10,
|
||||
FontWeight = FontWeights.Bold,
|
||||
HorizontalAlignment = HorizontalAlignment.Center,
|
||||
@@ -233,7 +233,7 @@ namespace Ink_Canvas
|
||||
ICCWaterMarkWhite.Visibility = Visibility.Collapsed;
|
||||
|
||||
// 设置为白板默认背景色
|
||||
Color defaultWhiteboardColor = Color.FromRgb(234, 235, 237);
|
||||
Color defaultWhiteboardColor = Color.FromRgb(255, 255, 255);
|
||||
|
||||
if (currentMode == 1) // 白板模式
|
||||
{
|
||||
@@ -319,7 +319,7 @@ namespace Ink_Canvas
|
||||
var separator = new Border
|
||||
{
|
||||
Height = 1,
|
||||
Background = new SolidColorBrush(Color.FromRgb(0xd4, 0xd4, 0xd8)),
|
||||
Background = (SolidColorBrush)Application.Current.FindResource("SettingsPageBorderBrush"),
|
||||
Margin = new Thickness(0, 12, 0, 12)
|
||||
};
|
||||
contentPanel.Children.Add(separator);
|
||||
@@ -328,7 +328,7 @@ namespace Ink_Canvas
|
||||
var colorTitle = new TextBlock
|
||||
{
|
||||
Text = "背景颜色",
|
||||
Foreground = new SolidColorBrush(Color.FromRgb(0x17, 0x25, 0x54)),
|
||||
Foreground = (SolidColorBrush)Application.Current.FindResource("TextForeground"),
|
||||
FontSize = 10,
|
||||
FontWeight = FontWeights.Bold,
|
||||
HorizontalAlignment = HorizontalAlignment.Center,
|
||||
@@ -342,7 +342,7 @@ namespace Ink_Canvas
|
||||
Width = 100,
|
||||
Height = 40,
|
||||
BorderThickness = new Thickness(1),
|
||||
BorderBrush = new SolidColorBrush(Color.FromRgb(0xd4, 0xd4, 0xd8)),
|
||||
BorderBrush = (SolidColorBrush)Application.Current.FindResource("SettingsPageBorderBrush"),
|
||||
Background = new SolidColorBrush(Colors.White),
|
||||
CornerRadius = new CornerRadius(4),
|
||||
Margin = new Thickness(0, 0, 0, 10),
|
||||
@@ -378,7 +378,7 @@ namespace Ink_Canvas
|
||||
// 先创建所有滑块控件
|
||||
// R滑块和文本框
|
||||
var rPanel = new StackPanel { Orientation = Orientation.Horizontal, Margin = new Thickness(10, 0, 10, 5) };
|
||||
var rLabel = new TextBlock { Text = "R:", Width = 20, VerticalAlignment = VerticalAlignment.Center };
|
||||
var rLabel = new TextBlock { Text = "R:", Width = 20, VerticalAlignment = VerticalAlignment.Center, Foreground = (SolidColorBrush)Application.Current.FindResource("TextForeground") };
|
||||
var rSlider = new Slider
|
||||
{
|
||||
Minimum = 0,
|
||||
@@ -393,12 +393,13 @@ namespace Ink_Canvas
|
||||
Text = currentBackgroundColor.R.ToString(),
|
||||
Width = 30,
|
||||
VerticalAlignment = VerticalAlignment.Center,
|
||||
TextAlignment = TextAlignment.Right
|
||||
TextAlignment = TextAlignment.Right,
|
||||
Foreground = (SolidColorBrush)Application.Current.FindResource("TextForeground")
|
||||
};
|
||||
|
||||
// G滑块和文本框
|
||||
var gPanel = new StackPanel { Orientation = Orientation.Horizontal, Margin = new Thickness(10, 0, 10, 5) };
|
||||
var gLabel = new TextBlock { Text = "G:", Width = 20, VerticalAlignment = VerticalAlignment.Center };
|
||||
var gLabel = new TextBlock { Text = "G:", Width = 20, VerticalAlignment = VerticalAlignment.Center, Foreground = (SolidColorBrush)Application.Current.FindResource("TextForeground") };
|
||||
var gSlider = new Slider
|
||||
{
|
||||
Minimum = 0,
|
||||
@@ -413,12 +414,13 @@ namespace Ink_Canvas
|
||||
Text = currentBackgroundColor.G.ToString(),
|
||||
Width = 30,
|
||||
VerticalAlignment = VerticalAlignment.Center,
|
||||
TextAlignment = TextAlignment.Right
|
||||
TextAlignment = TextAlignment.Right,
|
||||
Foreground = (SolidColorBrush)Application.Current.FindResource("TextForeground")
|
||||
};
|
||||
|
||||
// B滑块和文本框
|
||||
var bPanel = new StackPanel { Orientation = Orientation.Horizontal, Margin = new Thickness(10, 0, 10, 5) };
|
||||
var bLabel = new TextBlock { Text = "B:", Width = 20, VerticalAlignment = VerticalAlignment.Center };
|
||||
var bLabel = new TextBlock { Text = "B:", Width = 20, VerticalAlignment = VerticalAlignment.Center, Foreground = (SolidColorBrush)Application.Current.FindResource("TextForeground") };
|
||||
var bSlider = new Slider
|
||||
{
|
||||
Minimum = 0,
|
||||
@@ -433,7 +435,8 @@ namespace Ink_Canvas
|
||||
Text = currentBackgroundColor.B.ToString(),
|
||||
Width = 30,
|
||||
VerticalAlignment = VerticalAlignment.Center,
|
||||
TextAlignment = TextAlignment.Right
|
||||
TextAlignment = TextAlignment.Right,
|
||||
Foreground = (SolidColorBrush)Application.Current.FindResource("TextForeground")
|
||||
};
|
||||
|
||||
// 现在添加事件处理程序
|
||||
@@ -854,4 +857,4 @@ namespace Ink_Canvas
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,10 @@ namespace Ink_Canvas
|
||||
|
||||
private void ColorSwitchCheck()
|
||||
{
|
||||
HideSubPanels("color");
|
||||
if (penType != 1)
|
||||
{
|
||||
HideSubPanels("color");
|
||||
}
|
||||
if (GridTransparencyFakeBackground.Background == Brushes.Transparent)
|
||||
{
|
||||
if (currentMode == 1)
|
||||
|
||||
@@ -1585,7 +1585,7 @@ namespace Ink_Canvas
|
||||
{
|
||||
isResizingImage = true;
|
||||
imageResizeStartPoint = e.GetPosition(inkCanvas);
|
||||
|
||||
|
||||
// 确定是哪个控制点
|
||||
activeResizeHandle = ellipse.Name;
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using Ink_Canvas.Helpers;
|
||||
using System;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
@@ -46,29 +45,35 @@ namespace Ink_Canvas
|
||||
}
|
||||
|
||||
// 绑定事件处理
|
||||
canvas.StylusDown += ((o, args) => {
|
||||
canvas.StylusDown += ((o, args) =>
|
||||
{
|
||||
e.Handled = true;
|
||||
if (args.StylusDevice.TabletDevice.Type == TabletDeviceType.Stylus) canvas.CaptureStylus();
|
||||
EraserOverlay_PointerDown(sender);
|
||||
});
|
||||
canvas.StylusUp += ((o, args) => {
|
||||
canvas.StylusUp += ((o, args) =>
|
||||
{
|
||||
e.Handled = true;
|
||||
if (args.StylusDevice.TabletDevice.Type == TabletDeviceType.Stylus) canvas.ReleaseStylusCapture();
|
||||
EraserOverlay_PointerUp(sender);
|
||||
});
|
||||
canvas.StylusMove += ((o, args) => {
|
||||
canvas.StylusMove += ((o, args) =>
|
||||
{
|
||||
e.Handled = true;
|
||||
EraserOverlay_PointerMove(sender, args.GetPosition(inkCanvas));
|
||||
});
|
||||
canvas.MouseDown += ((o, args) => {
|
||||
canvas.MouseDown += ((o, args) =>
|
||||
{
|
||||
canvas.CaptureMouse();
|
||||
EraserOverlay_PointerDown(sender);
|
||||
});
|
||||
canvas.MouseUp += ((o, args) => {
|
||||
canvas.MouseUp += ((o, args) =>
|
||||
{
|
||||
canvas.ReleaseMouseCapture();
|
||||
EraserOverlay_PointerUp(sender);
|
||||
});
|
||||
canvas.MouseMove += ((o, args) => {
|
||||
canvas.MouseMove += ((o, args) =>
|
||||
{
|
||||
EraserOverlay_PointerMove(sender, args.GetPosition(inkCanvas));
|
||||
});
|
||||
|
||||
@@ -86,7 +91,7 @@ namespace Ink_Canvas
|
||||
// 根据橡皮擦形状选择对应的图像资源
|
||||
string resourceKey = isEraserCircleShape ? "EllipseEraserImageSource" : "RectangleEraserImageSource";
|
||||
var imageSource = TryFindResource(resourceKey) as DrawingImage;
|
||||
|
||||
|
||||
if (imageSource != null)
|
||||
{
|
||||
eraserFeedback.Source = imageSource;
|
||||
@@ -301,8 +306,8 @@ namespace Ink_Canvas
|
||||
if (isEraserCircleShape)
|
||||
{
|
||||
eraserWidth = k * 90; // 圆形橡皮擦
|
||||
}
|
||||
else
|
||||
}
|
||||
else
|
||||
{
|
||||
eraserWidth = k * 90 * 0.6; // 矩形橡皮擦宽度
|
||||
}
|
||||
|
||||
@@ -80,25 +80,24 @@ namespace Ink_Canvas
|
||||
// 多指书写模式启用时,手势功能被禁用
|
||||
TwoFingerGestureSimpleStackPanel.Opacity = 0.5;
|
||||
TwoFingerGestureSimpleStackPanel.IsHitTestVisible = false;
|
||||
EnableTwoFingerGestureBtn.Source =
|
||||
new BitmapImage(new Uri("/Resources/new-icons/gesture.png", UriKind.Relative));
|
||||
EnableTwoFingerGestureBtn.Source = (BitmapImage)Application.Current.FindResource("GestureIcon");
|
||||
|
||||
// 根据主题设置颜色
|
||||
if (Settings.Appearance.Theme == 1) // 深色主题
|
||||
{
|
||||
BoardGesture.Background = new SolidColorBrush(Color.FromRgb(42, 42, 42));
|
||||
BoardGestureGeometry.Brush = new SolidColorBrush(Color.FromRgb(255, 255, 255));
|
||||
BoardGestureGeometry2.Brush = new SolidColorBrush(Color.FromRgb(255, 255, 255));
|
||||
BoardGestureLabel.Foreground = new SolidColorBrush(Color.FromRgb(255, 255, 255));
|
||||
BoardGesture.BorderBrush = new SolidColorBrush(Color.FromRgb(85, 85, 85));
|
||||
BoardGesture.Background = new SolidColorBrush(Color.FromRgb(42, 42, 42));
|
||||
BoardGestureGeometry.Brush = new SolidColorBrush(Color.FromRgb(255, 255, 255));
|
||||
BoardGestureGeometry2.Brush = new SolidColorBrush(Color.FromRgb(255, 255, 255));
|
||||
BoardGestureLabel.Foreground = new SolidColorBrush(Color.FromRgb(255, 255, 255));
|
||||
BoardGesture.BorderBrush = new SolidColorBrush(Color.FromRgb(85, 85, 85));
|
||||
}
|
||||
else // 浅色主题或跟随系统
|
||||
{
|
||||
BoardGesture.Background = new SolidColorBrush(Color.FromRgb(244, 244, 245));
|
||||
BoardGestureGeometry.Brush = new SolidColorBrush(Color.FromRgb(24, 24, 27));
|
||||
BoardGestureGeometry2.Brush = new SolidColorBrush(Color.FromRgb(24, 24, 27));
|
||||
BoardGestureLabel.Foreground = new SolidColorBrush(Color.FromRgb(24, 24, 27));
|
||||
BoardGesture.BorderBrush = new SolidColorBrush(Color.FromRgb(161, 161, 170));
|
||||
BoardGesture.Background = new SolidColorBrush(Color.FromRgb(244, 244, 245));
|
||||
BoardGestureGeometry.Brush = new SolidColorBrush(Color.FromRgb(24, 24, 27));
|
||||
BoardGestureGeometry2.Brush = new SolidColorBrush(Color.FromRgb(24, 24, 27));
|
||||
BoardGestureLabel.Foreground = new SolidColorBrush(Color.FromRgb(24, 24, 27));
|
||||
BoardGesture.BorderBrush = new SolidColorBrush(Color.FromRgb(161, 161, 170));
|
||||
}
|
||||
BoardGestureGeometry.Geometry = Geometry.Parse(XamlGraphicsIconGeometries.DisabledGestureIcon);
|
||||
BoardGestureGeometry2.Geometry = Geometry.Parse("F0 M24,24z M0,0z");
|
||||
@@ -111,14 +110,13 @@ namespace Ink_Canvas
|
||||
// 多指书写模式禁用时,根据实际手势功能状态显示
|
||||
TwoFingerGestureSimpleStackPanel.Opacity = 1;
|
||||
TwoFingerGestureSimpleStackPanel.IsHitTestVisible = true;
|
||||
|
||||
|
||||
// 检查是否有任何手势功能启用
|
||||
bool hasGestureEnabled = Settings.Gesture.IsEnableTwoFingerGesture;
|
||||
|
||||
|
||||
if (hasGestureEnabled)
|
||||
{
|
||||
EnableTwoFingerGestureBtn.Source =
|
||||
new BitmapImage(new Uri("/Resources/new-icons/gesture-enabled.png", UriKind.Relative));
|
||||
EnableTwoFingerGestureBtn.Source = (BitmapImage)Application.Current.FindResource("GestureIconEnabled");
|
||||
|
||||
BoardGesture.Background = new SolidColorBrush(Color.FromRgb(37, 99, 235));
|
||||
BoardGestureGeometry.Brush = new SolidColorBrush(Colors.GhostWhite);
|
||||
@@ -130,25 +128,24 @@ namespace Ink_Canvas
|
||||
}
|
||||
else
|
||||
{
|
||||
EnableTwoFingerGestureBtn.Source =
|
||||
new BitmapImage(new Uri("/Resources/new-icons/gesture.png", UriKind.Relative));
|
||||
EnableTwoFingerGestureBtn.Source = (BitmapImage)Application.Current.FindResource("GestureIcon");
|
||||
|
||||
// 根据主题设置颜色
|
||||
if (Settings.Appearance.Theme == 1) // 深色主题
|
||||
{
|
||||
BoardGesture.Background = new SolidColorBrush(Color.FromRgb(42, 42, 42));
|
||||
BoardGestureGeometry.Brush = new SolidColorBrush(Color.FromRgb(255, 255, 255));
|
||||
BoardGestureGeometry2.Brush = new SolidColorBrush(Color.FromRgb(255, 255, 255));
|
||||
BoardGestureLabel.Foreground = new SolidColorBrush(Color.FromRgb(255, 255, 255));
|
||||
BoardGesture.BorderBrush = new SolidColorBrush(Color.FromRgb(85, 85, 85));
|
||||
BoardGesture.Background = new SolidColorBrush(Color.FromRgb(42, 42, 42));
|
||||
BoardGestureGeometry.Brush = new SolidColorBrush(Color.FromRgb(255, 255, 255));
|
||||
BoardGestureGeometry2.Brush = new SolidColorBrush(Color.FromRgb(255, 255, 255));
|
||||
BoardGestureLabel.Foreground = new SolidColorBrush(Color.FromRgb(255, 255, 255));
|
||||
BoardGesture.BorderBrush = new SolidColorBrush(Color.FromRgb(85, 85, 85));
|
||||
}
|
||||
else // 浅色主题或跟随系统
|
||||
{
|
||||
BoardGesture.Background = new SolidColorBrush(Color.FromRgb(244, 244, 245));
|
||||
BoardGestureGeometry.Brush = new SolidColorBrush(Color.FromRgb(24, 24, 27));
|
||||
BoardGestureGeometry2.Brush = new SolidColorBrush(Color.FromRgb(24, 24, 27));
|
||||
BoardGestureLabel.Foreground = new SolidColorBrush(Color.FromRgb(24, 24, 27));
|
||||
BoardGesture.BorderBrush = new SolidColorBrush(Color.FromRgb(161, 161, 170));
|
||||
BoardGestureGeometry.Brush = new SolidColorBrush(Color.FromRgb(24, 24, 27));
|
||||
BoardGestureGeometry2.Brush = new SolidColorBrush(Color.FromRgb(24, 24, 27));
|
||||
BoardGestureLabel.Foreground = new SolidColorBrush(Color.FromRgb(24, 24, 27));
|
||||
BoardGesture.BorderBrush = new SolidColorBrush(Color.FromRgb(161, 161, 170));
|
||||
}
|
||||
BoardGestureGeometry.Geometry = Geometry.Parse(XamlGraphicsIconGeometries.DisabledGestureIcon);
|
||||
BoardGestureGeometry2.Geometry = Geometry.Parse("F0 M24,24z M0,0z");
|
||||
@@ -176,11 +173,16 @@ namespace Ink_Canvas
|
||||
return;
|
||||
}
|
||||
|
||||
// 在屏幕模式(非放映模式)下,不显示手势按钮
|
||||
if (currentMode == 0)
|
||||
{
|
||||
EnableTwoFingerGestureBorder.Visibility = Visibility.Collapsed;
|
||||
return;
|
||||
if (GridTransparencyFakeBackground.Background != Brushes.Transparent && isVisible)
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
EnableTwoFingerGestureBorder.Visibility = Visibility.Collapsed;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (StackPanelCanvasControls.Visibility != Visibility.Visible
|
||||
@@ -383,7 +385,7 @@ namespace Ink_Canvas
|
||||
var slideAnimation = new DoubleAnimation
|
||||
{
|
||||
From = 0, // 滑动距离
|
||||
To = BorderSettings.RenderTransform.Value.OffsetX - 440,
|
||||
To = BorderSettings.RenderTransform.Value.OffsetX - 490,
|
||||
Duration = TimeSpan.FromSeconds(0.6)
|
||||
};
|
||||
slideAnimation.EasingFunction = new CubicEase { EasingMode = EasingMode.EaseOut };
|
||||
@@ -396,18 +398,13 @@ namespace Ink_Canvas
|
||||
{
|
||||
BorderSettings.Visibility = Visibility.Collapsed;
|
||||
isOpeningOrHidingSettingsPane = false;
|
||||
// 在设置面板完全关闭后,根据情况恢复无焦点模式状态
|
||||
if (!userChangedNoFocusModeInSettings && wasNoFocusModeBeforeSettings)
|
||||
if (isTemporarilyDisablingNoFocusMode)
|
||||
{
|
||||
// 如果用户没有在设置中修改无焦点模式,则恢复之前的状态
|
||||
Settings.Advanced.IsNoFocusMode = true;
|
||||
ToggleSwitchNoFocusMode.IsOn = true; // 同步更新设置面板中的开关状态
|
||||
isTemporarilyDisablingNoFocusMode = false;
|
||||
ApplyNoFocusMode();
|
||||
}
|
||||
// 如果用户在设置中修改了无焦点模式,则保持用户的修改
|
||||
};
|
||||
|
||||
BorderSettings.Visibility = Visibility.Visible;
|
||||
BorderSettings.RenderTransform = new TranslateTransform();
|
||||
|
||||
isOpeningOrHidingSettingsPane = true;
|
||||
@@ -443,44 +440,58 @@ namespace Ink_Canvas
|
||||
// 根据主题设置颜色
|
||||
if (Settings.Appearance.Theme == 1) // 深色主题
|
||||
{
|
||||
BoardPen.Background = new SolidColorBrush(Color.FromRgb(42, 42, 42));
|
||||
BoardSelect.Background = new SolidColorBrush(Color.FromRgb(42, 42, 42));
|
||||
BoardEraser.Background = new SolidColorBrush(Color.FromRgb(42, 42, 42));
|
||||
BoardSelectGeometry.Brush = new SolidColorBrush(Color.FromRgb(255, 255, 255));
|
||||
BoardPenGeometry.Brush = new SolidColorBrush(Color.FromRgb(255, 255, 255));
|
||||
BoardEraserGeometry.Brush = new SolidColorBrush(Color.FromRgb(255, 255, 255));
|
||||
BoardPenLabel.Foreground = new SolidColorBrush(Color.FromRgb(255, 255, 255));
|
||||
BoardSelectLabel.Foreground = new SolidColorBrush(Color.FromRgb(255, 255, 255));
|
||||
BoardEraserLabel.Foreground = new SolidColorBrush(Color.FromRgb(255, 255, 255));
|
||||
BoardSelect.BorderBrush = new SolidColorBrush(Color.FromRgb(85, 85, 85));
|
||||
BoardEraser.BorderBrush = new SolidColorBrush(Color.FromRgb(85, 85, 85));
|
||||
BoardPen.BorderBrush = new SolidColorBrush(Color.FromRgb(85, 85, 85));
|
||||
BoardPen.Background = new SolidColorBrush(Color.FromRgb(42, 42, 42));
|
||||
BoardSelect.Background = new SolidColorBrush(Color.FromRgb(42, 42, 42));
|
||||
BoardEraser.Background = new SolidColorBrush(Color.FromRgb(42, 42, 42));
|
||||
BoardSelectGeometry.Brush = new SolidColorBrush(Color.FromRgb(255, 255, 255));
|
||||
BoardPenGeometry.Brush = new SolidColorBrush(Color.FromRgb(255, 255, 255));
|
||||
BoardEraserGeometry.Brush = new SolidColorBrush(Color.FromRgb(255, 255, 255));
|
||||
BoardPenLabel.Foreground = new SolidColorBrush(Color.FromRgb(255, 255, 255));
|
||||
BoardSelectLabel.Foreground = new SolidColorBrush(Color.FromRgb(255, 255, 255));
|
||||
BoardEraserLabel.Foreground = new SolidColorBrush(Color.FromRgb(255, 255, 255));
|
||||
BoardSelect.BorderBrush = new SolidColorBrush(Color.FromRgb(85, 85, 85));
|
||||
BoardEraser.BorderBrush = new SolidColorBrush(Color.FromRgb(85, 85, 85));
|
||||
BoardPen.BorderBrush = new SolidColorBrush(Color.FromRgb(85, 85, 85));
|
||||
}
|
||||
else // 浅色主题或跟随系统
|
||||
{
|
||||
BoardPen.Background = new SolidColorBrush(Color.FromRgb(244, 244, 245));
|
||||
BoardSelect.Background = new SolidColorBrush(Color.FromRgb(244, 244, 245));
|
||||
BoardEraser.Background = new SolidColorBrush(Color.FromRgb(244, 244, 245));
|
||||
BoardSelectGeometry.Brush = new SolidColorBrush(Color.FromRgb(24, 24, 27));
|
||||
BoardPenGeometry.Brush = new SolidColorBrush(Color.FromRgb(24, 24, 27));
|
||||
BoardEraserGeometry.Brush = new SolidColorBrush(Color.FromRgb(24, 24, 27));
|
||||
BoardPenLabel.Foreground = new SolidColorBrush(Color.FromRgb(24, 24, 27));
|
||||
BoardSelectLabel.Foreground = new SolidColorBrush(Color.FromRgb(24, 24, 27));
|
||||
BoardEraserLabel.Foreground = new SolidColorBrush(Color.FromRgb(24, 24, 27));
|
||||
BoardSelect.BorderBrush = new SolidColorBrush(Color.FromRgb(161, 161, 170));
|
||||
BoardEraser.BorderBrush = new SolidColorBrush(Color.FromRgb(161, 161, 170));
|
||||
BoardPen.BorderBrush = new SolidColorBrush(Color.FromRgb(161, 161, 170));
|
||||
BoardPen.Background = new SolidColorBrush(Color.FromRgb(244, 244, 245));
|
||||
BoardSelect.Background = new SolidColorBrush(Color.FromRgb(244, 244, 245));
|
||||
BoardEraser.Background = new SolidColorBrush(Color.FromRgb(244, 244, 245));
|
||||
BoardSelectGeometry.Brush = new SolidColorBrush(Color.FromRgb(24, 24, 27));
|
||||
BoardPenGeometry.Brush = new SolidColorBrush(Color.FromRgb(24, 24, 27));
|
||||
BoardEraserGeometry.Brush = new SolidColorBrush(Color.FromRgb(24, 24, 27));
|
||||
BoardPenLabel.Foreground = new SolidColorBrush(Color.FromRgb(24, 24, 27));
|
||||
BoardSelectLabel.Foreground = new SolidColorBrush(Color.FromRgb(24, 24, 27));
|
||||
BoardEraserLabel.Foreground = new SolidColorBrush(Color.FromRgb(24, 24, 27));
|
||||
BoardSelect.BorderBrush = new SolidColorBrush(Color.FromRgb(161, 161, 170));
|
||||
BoardEraser.BorderBrush = new SolidColorBrush(Color.FromRgb(161, 161, 170));
|
||||
BoardPen.BorderBrush = new SolidColorBrush(Color.FromRgb(161, 161, 170));
|
||||
}
|
||||
|
||||
HideFloatingBarHighlight();
|
||||
}
|
||||
|
||||
// 根据主题选择高光颜色
|
||||
Color highlightColor;
|
||||
bool isDarkTheme = Settings.Appearance.Theme == 1 ||
|
||||
(Settings.Appearance.Theme == 2 && !IsSystemThemeLight());
|
||||
|
||||
if (isDarkTheme)
|
||||
{
|
||||
highlightColor = Color.FromRgb(102, 204, 255); // #66ccff for dark theme
|
||||
}
|
||||
else
|
||||
{
|
||||
highlightColor = Color.FromRgb(30, 58, 138); // Keep current color for light theme
|
||||
}
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case "pen":
|
||||
case "color":
|
||||
{
|
||||
PenIconGeometry.Brush = new SolidColorBrush(Color.FromRgb(30, 58, 138));
|
||||
PenIconGeometry.Brush = new SolidColorBrush(highlightColor);
|
||||
PenIconGeometry.Geometry = Geometry.Parse(GetCorrectIcon("pen", true));
|
||||
BoardPen.Background = new SolidColorBrush(Color.FromRgb(37, 99, 235));
|
||||
BoardPen.BorderBrush = new SolidColorBrush(Color.FromRgb(37, 99, 235));
|
||||
@@ -492,7 +503,7 @@ namespace Ink_Canvas
|
||||
}
|
||||
case "eraser":
|
||||
{
|
||||
CircleEraserIconGeometry.Brush = new SolidColorBrush(Color.FromRgb(30, 58, 138));
|
||||
CircleEraserIconGeometry.Brush = new SolidColorBrush(highlightColor);
|
||||
CircleEraserIconGeometry.Geometry =
|
||||
Geometry.Parse(GetCorrectIcon("eraserCircle", true));
|
||||
BoardEraser.Background = new SolidColorBrush(Color.FromRgb(37, 99, 235));
|
||||
@@ -505,7 +516,7 @@ namespace Ink_Canvas
|
||||
}
|
||||
case "eraserByStrokes":
|
||||
{
|
||||
StrokeEraserIconGeometry.Brush = new SolidColorBrush(Color.FromRgb(30, 58, 138));
|
||||
StrokeEraserIconGeometry.Brush = new SolidColorBrush(highlightColor);
|
||||
StrokeEraserIconGeometry.Geometry =
|
||||
Geometry.Parse(GetCorrectIcon("eraserStroke", true));
|
||||
BoardEraser.Background = new SolidColorBrush(Color.FromRgb(37, 99, 235));
|
||||
@@ -518,7 +529,7 @@ namespace Ink_Canvas
|
||||
}
|
||||
case "select":
|
||||
{
|
||||
LassoSelectIconGeometry.Brush = new SolidColorBrush(Color.FromRgb(30, 58, 138));
|
||||
LassoSelectIconGeometry.Brush = new SolidColorBrush(highlightColor);
|
||||
LassoSelectIconGeometry.Geometry =
|
||||
Geometry.Parse(GetCorrectIcon("lassoSelect", true));
|
||||
BoardSelect.Background = new SolidColorBrush(Color.FromRgb(37, 99, 235));
|
||||
@@ -531,23 +542,23 @@ namespace Ink_Canvas
|
||||
}
|
||||
case "cursor":
|
||||
{
|
||||
CursorIconGeometry.Brush = new SolidColorBrush(Color.FromRgb(30, 58, 138));
|
||||
CursorIconGeometry.Brush = new SolidColorBrush(highlightColor);
|
||||
CursorIconGeometry.Geometry =
|
||||
Geometry.Parse(GetCorrectIcon("cursor", true));
|
||||
// 根据主题设置颜色
|
||||
if (Settings.Appearance.Theme == 1) // 深色主题
|
||||
{
|
||||
BoardPen.Background = new SolidColorBrush(Color.FromRgb(42, 42, 42));
|
||||
BoardPen.BorderBrush = new SolidColorBrush(Color.FromRgb(85, 85, 85));
|
||||
BoardPenGeometry.Brush = new SolidColorBrush(Color.FromRgb(255, 255, 255));
|
||||
BoardPenLabel.Foreground = new SolidColorBrush(Color.FromRgb(255, 255, 255));
|
||||
BoardPen.Background = new SolidColorBrush(Color.FromRgb(42, 42, 42));
|
||||
BoardPen.BorderBrush = new SolidColorBrush(Color.FromRgb(85, 85, 85));
|
||||
BoardPenGeometry.Brush = new SolidColorBrush(Color.FromRgb(255, 255, 255));
|
||||
BoardPenLabel.Foreground = new SolidColorBrush(Color.FromRgb(255, 255, 255));
|
||||
}
|
||||
else // 浅色主题或跟随系统
|
||||
{
|
||||
BoardPen.Background = new SolidColorBrush(Color.FromRgb(244, 244, 245));
|
||||
BoardPen.BorderBrush = new SolidColorBrush(Color.FromRgb(161, 161, 170));
|
||||
BoardPenGeometry.Brush = new SolidColorBrush(Color.FromRgb(24, 24, 27));
|
||||
BoardPenLabel.Foreground = new SolidColorBrush(Color.FromRgb(24, 24, 27));
|
||||
BoardPen.Background = new SolidColorBrush(Color.FromRgb(244, 244, 245));
|
||||
BoardPen.BorderBrush = new SolidColorBrush(Color.FromRgb(161, 161, 170));
|
||||
BoardPenGeometry.Brush = new SolidColorBrush(Color.FromRgb(24, 24, 27));
|
||||
BoardPenLabel.Foreground = new SolidColorBrush(Color.FromRgb(24, 24, 27));
|
||||
}
|
||||
|
||||
SetFloatingBarHighlightPosition("cursor");
|
||||
@@ -915,7 +926,7 @@ namespace Ink_Canvas
|
||||
#region 主要的工具按鈕事件
|
||||
|
||||
/// <summary>
|
||||
/// 浮動工具欄的"套索選"按鈕事件,重定向到舊UI的<c>BtnSelect_Click</c>方法
|
||||
/// 浮動工具欄的"套索選"按鈕事件,重定向到舊UI的<c>BtnSelect_Click</c>方法
|
||||
/// </summary>
|
||||
/// <param name="sender">sender</param>
|
||||
/// <param name="e">MouseButtonEventArgs</param>
|
||||
@@ -1041,7 +1052,18 @@ namespace Ink_Canvas
|
||||
AnimationsHelper.HideWithSlideAndFade(BoardBorderTools);
|
||||
AnimationsHelper.HideWithSlideAndFade(BoardImageOptionsPanel);
|
||||
|
||||
new CountdownTimerWindow().Show();
|
||||
// 参考老计时器的窗口置顶功能:在白板模式下停止窗口置顶
|
||||
if (currentMode == 1) // 白板模式
|
||||
{
|
||||
Topmost = false;
|
||||
}
|
||||
|
||||
var timerWindow = CountdownTimerWindow.CreateTimerWindow();
|
||||
timerWindow.Show();
|
||||
if (currentMode == 1) // 白板模式
|
||||
{
|
||||
timerWindow.Topmost = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void OperatingGuideWindowIcon_MouseUp(object sender, MouseButtonEventArgs e)
|
||||
@@ -1065,11 +1087,20 @@ namespace Ink_Canvas
|
||||
AnimationsHelper.HideWithSlideAndFade(BoardBorderTools);
|
||||
AnimationsHelper.HideWithSlideAndFade(BoardImageOptionsPanel);
|
||||
|
||||
var randWindow = new RandWindow(Settings);
|
||||
randWindow.Show();
|
||||
// 根据设置决定使用哪个点名窗口
|
||||
if (Settings.RandSettings.UseNewRollCallUI)
|
||||
{
|
||||
// 使用新点名UI - 随机抽模式
|
||||
new NewStyleRollCallWindow(Settings, false).ShowDialog();
|
||||
}
|
||||
else
|
||||
{
|
||||
// 使用默认的随机点名窗口
|
||||
var randWindow = new RandWindow(Settings);
|
||||
randWindow.Show();
|
||||
|
||||
// 使用延迟确保窗口完全显示后再强制置顶
|
||||
randWindow.Dispatcher.BeginInvoke(new Action(() =>
|
||||
// 使用延迟确保窗口完全显示后再强制置顶
|
||||
randWindow.Dispatcher.BeginInvoke(new Action(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -1106,6 +1137,7 @@ namespace Ink_Canvas
|
||||
LogHelper.WriteLogToFile($"强制置顶RandWindow失败: {ex.Message}", LogHelper.LogType.Error);
|
||||
}
|
||||
}), DispatcherPriority.Loaded);
|
||||
}
|
||||
}
|
||||
|
||||
public void CheckEraserTypeTab()
|
||||
@@ -1212,14 +1244,30 @@ namespace Ink_Canvas
|
||||
{
|
||||
MessageBox.Show("无法调用外部点名:" + ex.Message);
|
||||
|
||||
// 调用失败时回退到默认的随机点名窗口
|
||||
new RandWindow(Settings, true).ShowDialog();
|
||||
// 调用失败时回退到相应的点名窗口
|
||||
if (Settings.RandSettings.UseNewRollCallUI)
|
||||
{
|
||||
new NewStyleRollCallWindow(Settings, true).ShowDialog(); // 单次抽模式
|
||||
}
|
||||
else
|
||||
{
|
||||
new RandWindow(Settings, true).ShowDialog();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 使用默认的随机点名窗口
|
||||
new RandWindow(Settings, true).ShowDialog();
|
||||
// 根据设置决定使用哪个点名窗口
|
||||
if (Settings.RandSettings.UseNewRollCallUI)
|
||||
{
|
||||
// 使用新点名UI - 单次抽模式
|
||||
new NewStyleRollCallWindow(Settings, true).ShowDialog();
|
||||
}
|
||||
else
|
||||
{
|
||||
// 使用默认的随机点名窗口
|
||||
new RandWindow(Settings, true).ShowDialog();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1357,12 +1405,12 @@ namespace Ink_Canvas
|
||||
BlackboardUIGridForInkReplay.IsHitTestVisible = true;
|
||||
inkCanvas.IsHitTestVisible = true;
|
||||
inkCanvas.IsManipulationEnabled = true;
|
||||
|
||||
|
||||
if (inkCanvas.EditingMode == InkCanvasEditingMode.None)
|
||||
{
|
||||
inkCanvas.EditingMode = InkCanvasEditingMode.Ink;
|
||||
}
|
||||
|
||||
|
||||
ResetTouchStates();
|
||||
});
|
||||
}).Start();
|
||||
@@ -1388,12 +1436,12 @@ namespace Ink_Canvas
|
||||
isStopInkReplay = true;
|
||||
inkCanvas.IsHitTestVisible = true;
|
||||
inkCanvas.IsManipulationEnabled = true;
|
||||
|
||||
|
||||
if (inkCanvas.EditingMode == InkCanvasEditingMode.None)
|
||||
{
|
||||
inkCanvas.EditingMode = InkCanvasEditingMode.Ink;
|
||||
}
|
||||
|
||||
|
||||
ResetTouchStates();
|
||||
}
|
||||
}
|
||||
@@ -1587,7 +1635,6 @@ namespace Ink_Canvas
|
||||
if (toolbarHeight == 0)
|
||||
{
|
||||
pos.Y = screenHeight - MarginFromEdge * ViewboxFloatingBarScaleTransform.ScaleY;
|
||||
LogHelper.WriteLogToFile($"任务栏隐藏,使用固定边距: {MarginFromEdge}");
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1601,7 +1648,6 @@ namespace Ink_Canvas
|
||||
{
|
||||
pos.Y = screenHeight - ViewboxFloatingBar.ActualHeight * ViewboxFloatingBarScaleTransform.ScaleY -
|
||||
3 * ViewboxFloatingBarScaleTransform.ScaleY;
|
||||
LogHelper.WriteLogToFile($"任务栏隐藏,使用固定高度: {ViewboxFloatingBar.ActualHeight}");
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1977,9 +2023,7 @@ namespace Ink_Canvas
|
||||
}
|
||||
|
||||
// 禁用高级橡皮擦系统
|
||||
DisableEraserOverlay();
|
||||
|
||||
ExitMultiTouchModeIfNeeded();
|
||||
DisableEraserOverlay();
|
||||
|
||||
SetFloatingBarHighlightPosition("pen");
|
||||
|
||||
@@ -2224,7 +2268,7 @@ namespace Ink_Canvas
|
||||
}
|
||||
|
||||
// 启用新的高级橡皮擦系统
|
||||
EnableEraserOverlay();
|
||||
EnableEraserOverlay();
|
||||
|
||||
// 使用新的高级橡皮擦系统
|
||||
// 使用集中化的工具模式切换方法
|
||||
@@ -2236,7 +2280,7 @@ namespace Ink_Canvas
|
||||
ApplyAdvancedEraserShape(); // 使用新的橡皮擦形状应用方法
|
||||
SetCursorBasedOnEditingMode(inkCanvas);
|
||||
HideSubPanels("eraser"); // 高亮橡皮按钮
|
||||
Trace.WriteLine($"Eraser: Eraser button clicked, current size: {eraserWidth}, circle: {isEraserCircleShape}");
|
||||
Trace.WriteLine($"Eraser: Eraser button clicked, current size: {eraserWidth}, circle: {isEraserCircleShape}");
|
||||
|
||||
if (isAlreadyEraser)
|
||||
{
|
||||
@@ -2265,7 +2309,7 @@ namespace Ink_Canvas
|
||||
drawingShapeMode = 0;
|
||||
|
||||
// 启用新的高级橡皮擦系统
|
||||
EnableEraserOverlay();
|
||||
EnableEraserOverlay();
|
||||
|
||||
// 使用新的高级橡皮擦系统
|
||||
// 使用集中化的工具模式切换方法
|
||||
@@ -2580,7 +2624,7 @@ namespace Ink_Canvas
|
||||
private void SelectIcon_MouseUp(object sender, RoutedEventArgs e)
|
||||
{
|
||||
// 禁用高级橡皮擦系统
|
||||
DisableEraserOverlay();
|
||||
DisableEraserOverlay();
|
||||
|
||||
forceEraser = true;
|
||||
drawingShapeMode = 0;
|
||||
@@ -2685,16 +2729,14 @@ namespace Ink_Canvas
|
||||
// 如果当前在设置面板中,需要先恢复无焦点模式状态
|
||||
if (BorderSettings.Visibility == Visibility.Visible)
|
||||
{
|
||||
// 如果用户没有在设置中修改无焦点模式,则恢复之前的状态
|
||||
if (!userChangedNoFocusModeInSettings && wasNoFocusModeBeforeSettings)
|
||||
if (isTemporarilyDisablingNoFocusMode)
|
||||
{
|
||||
Settings.Advanced.IsNoFocusMode = true;
|
||||
ToggleSwitchNoFocusMode.IsOn = true;
|
||||
isTemporarilyDisablingNoFocusMode = false;
|
||||
ApplyNoFocusMode();
|
||||
}
|
||||
SaveSettingsToFile();
|
||||
}
|
||||
|
||||
|
||||
App.IsAppExitByUser = true;
|
||||
// 不设置 CloseIsFromButton = true,让它也经过确认流程
|
||||
Close();
|
||||
@@ -2704,16 +2746,14 @@ namespace Ink_Canvas
|
||||
{
|
||||
if (BorderSettings.Visibility == Visibility.Visible)
|
||||
{
|
||||
// 如果用户没有在设置中修改无焦点模式,则恢复之前的状态
|
||||
if (!userChangedNoFocusModeInSettings && wasNoFocusModeBeforeSettings)
|
||||
if (isTemporarilyDisablingNoFocusMode)
|
||||
{
|
||||
Settings.Advanced.IsNoFocusMode = true;
|
||||
ToggleSwitchNoFocusMode.IsOn = true;
|
||||
isTemporarilyDisablingNoFocusMode = false;
|
||||
ApplyNoFocusMode();
|
||||
}
|
||||
SaveSettingsToFile();
|
||||
}
|
||||
|
||||
|
||||
Process.Start(System.Windows.Forms.Application.ExecutablePath, "-m");
|
||||
App.IsAppExitByUser = true;
|
||||
// 不设置 CloseIsFromButton = true,让它也经过确认流程
|
||||
@@ -2754,12 +2794,12 @@ namespace Ink_Canvas
|
||||
}
|
||||
else
|
||||
{
|
||||
// 临时禁用无焦点模式以避免下拉选项被遮挡
|
||||
BorderSettings.Visibility = Visibility.Visible;
|
||||
wasNoFocusModeBeforeSettings = Settings.Advanced.IsNoFocusMode;
|
||||
userChangedNoFocusModeInSettings = false; // 重置用户修改标志
|
||||
if (wasNoFocusModeBeforeSettings)
|
||||
{
|
||||
Settings.Advanced.IsNoFocusMode = false;
|
||||
isTemporarilyDisablingNoFocusMode = true;
|
||||
ApplyNoFocusMode();
|
||||
}
|
||||
|
||||
@@ -2772,7 +2812,7 @@ namespace Ink_Canvas
|
||||
// 滑动动画
|
||||
var slideAnimation = new DoubleAnimation
|
||||
{
|
||||
From = BorderSettings.RenderTransform.Value.OffsetX - 440, // 滑动距离
|
||||
From = BorderSettings.RenderTransform.Value.OffsetX - 490, // 滑动距离
|
||||
To = 0,
|
||||
Duration = TimeSpan.FromSeconds(0.6)
|
||||
};
|
||||
@@ -2784,7 +2824,6 @@ namespace Ink_Canvas
|
||||
|
||||
sb.Completed += (s, _) => { isOpeningOrHidingSettingsPane = false; };
|
||||
|
||||
BorderSettings.Visibility = Visibility.Visible;
|
||||
BorderSettings.RenderTransform = new TranslateTransform();
|
||||
|
||||
isOpeningOrHidingSettingsPane = true;
|
||||
@@ -2827,43 +2866,14 @@ namespace Ink_Canvas
|
||||
// 恢复非笔画元素
|
||||
RestoreNonStrokeElements(preservedElements);
|
||||
|
||||
CancelSingleFingerDragMode();
|
||||
|
||||
if (Settings.Canvas.ClearCanvasAndClearTimeMachine) timeMachine.ClearStrokeHistory();
|
||||
|
||||
// 清空墨迹后模拟用户重新手动开关多指书写功能
|
||||
SimulateMultiTouchToggle();
|
||||
CancelSingleFingerDragMode();
|
||||
|
||||
}
|
||||
|
||||
private bool lastIsInMultiTouchMode;
|
||||
|
||||
/// <summary>
|
||||
/// 模拟用户重新手动开关多指书写功能
|
||||
/// </summary>
|
||||
private void SimulateMultiTouchToggle()
|
||||
{
|
||||
try
|
||||
{
|
||||
// 检查多指书写模式是否启用
|
||||
if (ToggleSwitchEnableMultiTouchMode != null && ToggleSwitchEnableMultiTouchMode.IsOn)
|
||||
{
|
||||
// 先关闭多指书写模式
|
||||
ToggleSwitchEnableMultiTouchMode.IsOn = false;
|
||||
|
||||
// 使用Dispatcher.BeginInvoke确保UI更新完成后再重新开启
|
||||
Dispatcher.BeginInvoke(new Action(() =>
|
||||
{
|
||||
// 重新开启多指书写模式
|
||||
ToggleSwitchEnableMultiTouchMode.IsOn = true;
|
||||
}), DispatcherPriority.Background);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogHelper.WriteLogToFile($"模拟多指书写开关时发生错误: {ex.Message}", LogHelper.LogType.Error);
|
||||
}
|
||||
}
|
||||
|
||||
private void CancelSingleFingerDragMode()
|
||||
{
|
||||
if (ToggleSwitchDrawShapeBorderAutoHide.IsOn) CollapseBorderDrawShape();
|
||||
@@ -2872,10 +2882,8 @@ namespace Ink_Canvas
|
||||
|
||||
if (isSingleFingerDragMode) BtnFingerDragMode_Click(BtnFingerDragMode, null);
|
||||
isLongPressSelected = false;
|
||||
|
||||
ResetTouchStates();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 重置所有触摸相关状态,
|
||||
/// </summary>
|
||||
@@ -2885,36 +2893,25 @@ namespace Ink_Canvas
|
||||
{
|
||||
// 清空触摸点计数器
|
||||
dec.Clear();
|
||||
|
||||
|
||||
// 重置单指拖动模式状态
|
||||
if (isSingleFingerDragMode)
|
||||
{
|
||||
isSingleFingerDragMode = false;
|
||||
if (BtnFingerDragMode != null)
|
||||
{
|
||||
BtnFingerDragMode.Content = "单指\n拖动";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 重置手掌擦状态
|
||||
if (isPalmEraserActive)
|
||||
{
|
||||
isPalmEraserActive = false;
|
||||
}
|
||||
|
||||
|
||||
// 确保触摸事件能正常响应
|
||||
inkCanvas.IsHitTestVisible = true;
|
||||
inkCanvas.IsManipulationEnabled = true;
|
||||
|
||||
|
||||
// 释放所有触摸捕获
|
||||
inkCanvas.ReleaseAllTouchCaptures();
|
||||
|
||||
|
||||
// 恢复UI元素的触摸响应
|
||||
ViewboxFloatingBar.IsHitTestVisible = true;
|
||||
BlackboardUIGridForInkReplay.IsHitTestVisible = true;
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -3003,10 +3000,18 @@ namespace Ink_Canvas
|
||||
// 新增:在屏幕模式下恢复基础浮动栏的显示
|
||||
ViewboxFloatingBar.Visibility = Visibility.Visible;
|
||||
|
||||
// 新增:退出白板时自动收纳功能
|
||||
// 新增:退出白板时自动收纳功能 - 等待浮动栏完全展开后再收纳
|
||||
if (Settings.Automation.IsAutoFoldWhenExitWhiteboard && !isFloatingBarFolded)
|
||||
{
|
||||
FoldFloatingBar_MouseUp(null, null);
|
||||
// 使用异步延迟,等待浮动栏展开动画完成后再收纳
|
||||
Task.Run(async () =>
|
||||
{
|
||||
await Task.Delay(700);
|
||||
await Dispatcher.InvokeAsync(() =>
|
||||
{
|
||||
FoldFloatingBar_MouseUp(new object(), null);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
if (BtnSwitchTheme.Content.ToString() == "浅色")
|
||||
@@ -3083,7 +3088,15 @@ namespace Ink_Canvas
|
||||
}
|
||||
|
||||
StackPanelPPTButtons.Visibility = Visibility.Collapsed;
|
||||
Topmost = false;
|
||||
|
||||
if (Settings.Advanced.EnableUIAccessTopMost)
|
||||
{
|
||||
Topmost = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Topmost = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -3683,6 +3696,34 @@ namespace Ink_Canvas
|
||||
break;
|
||||
}
|
||||
|
||||
// 根据主题设置高光颜色
|
||||
Color highlightBackgroundColor;
|
||||
Color highlightBarColor;
|
||||
bool isDarkTheme = Settings.Appearance.Theme == 1 ||
|
||||
(Settings.Appearance.Theme == 2 && !IsSystemThemeLight());
|
||||
|
||||
if (isDarkTheme)
|
||||
{
|
||||
highlightBackgroundColor = Color.FromArgb(21, 102, 204, 255);
|
||||
highlightBarColor = Color.FromRgb(102, 204, 255);
|
||||
}
|
||||
else
|
||||
{
|
||||
highlightBackgroundColor = Color.FromArgb(21, 59, 130, 246);
|
||||
highlightBarColor = Color.FromRgb(37, 99, 235);
|
||||
}
|
||||
|
||||
// 设置高光背景颜色
|
||||
FloatingbarSelectionBG.Background = new SolidColorBrush(highlightBackgroundColor);
|
||||
if (FloatingbarSelectionBG.Child is System.Windows.Controls.Canvas canvas && canvas.Children.Count > 0)
|
||||
{
|
||||
var firstChild = canvas.Children[0];
|
||||
if (firstChild is Border innerBorder)
|
||||
{
|
||||
innerBorder.Background = new SolidColorBrush(highlightBarColor);
|
||||
}
|
||||
}
|
||||
|
||||
// 设置高光位置
|
||||
FloatingbarSelectionBG.Visibility = Visibility.Visible;
|
||||
System.Windows.Controls.Canvas.SetLeft(FloatingbarSelectionBG, position);
|
||||
|
||||
@@ -18,17 +18,17 @@ namespace Ink_Canvas
|
||||
try
|
||||
{
|
||||
_floatingWindowInterceptorManager = new FloatingWindowInterceptorManager();
|
||||
|
||||
|
||||
// 订阅事件
|
||||
_floatingWindowInterceptorManager.WindowIntercepted += OnFloatingWindowIntercepted;
|
||||
_floatingWindowInterceptorManager.WindowRestored += OnFloatingWindowRestored;
|
||||
|
||||
|
||||
// 初始化拦截器
|
||||
_floatingWindowInterceptorManager.Initialize(Settings.Automation.FloatingWindowInterceptor);
|
||||
|
||||
|
||||
// 加载UI状态
|
||||
LoadFloatingWindowInterceptorUI();
|
||||
|
||||
|
||||
LogHelper.WriteLogToFile("悬浮窗拦截管理器初始化完成", LogHelper.LogType.Event);
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -48,7 +48,7 @@ namespace Ink_Canvas
|
||||
|
||||
// 设置主开关状态
|
||||
ToggleSwitchFloatingWindowInterceptorEnabled.IsOn = Settings.Automation.FloatingWindowInterceptor.IsEnabled;
|
||||
|
||||
|
||||
// 设置各个拦截规则的状态
|
||||
foreach (var kvp in Settings.Automation.FloatingWindowInterceptor.InterceptRules)
|
||||
{
|
||||
@@ -59,7 +59,7 @@ namespace Ink_Canvas
|
||||
toggle.IsOn = kvp.Value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 更新UI可见性
|
||||
UpdateFloatingWindowInterceptorUI();
|
||||
}
|
||||
@@ -78,16 +78,16 @@ namespace Ink_Canvas
|
||||
{
|
||||
var isEnabled = Settings.Automation.FloatingWindowInterceptor.IsEnabled;
|
||||
FloatingWindowInterceptorGrid.Visibility = isEnabled ? Visibility.Visible : Visibility.Collapsed;
|
||||
|
||||
|
||||
// 计算启用的规则数量
|
||||
var enabledRulesCount = Settings.Automation.FloatingWindowInterceptor.InterceptRules.Where(kvp => kvp.Value).Count();
|
||||
var totalRulesCount = Settings.Automation.FloatingWindowInterceptor.InterceptRules.Count;
|
||||
|
||||
|
||||
// 更新状态文本
|
||||
if (_floatingWindowInterceptorManager != null)
|
||||
{
|
||||
var stats = _floatingWindowInterceptorManager.GetStatistics();
|
||||
TextBlockFloatingWindowInterceptorStatus.Text = stats.IsRunning
|
||||
TextBlockFloatingWindowInterceptorStatus.Text = stats.IsRunning
|
||||
? $"拦截器运行中 - 已启用 {enabledRulesCount}/{totalRulesCount} 个规则"
|
||||
: $"拦截器未启动 - 已启用 {enabledRulesCount}/{totalRulesCount} 个规则";
|
||||
}
|
||||
@@ -150,11 +150,11 @@ namespace Ink_Canvas
|
||||
private void ToggleSwitchFloatingWindowInterceptorEnabled_Toggled(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (!isLoaded) return;
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
Settings.Automation.FloatingWindowInterceptor.IsEnabled = ToggleSwitchFloatingWindowInterceptorEnabled.IsOn;
|
||||
|
||||
|
||||
if (_floatingWindowInterceptorManager != null)
|
||||
{
|
||||
if (Settings.Automation.FloatingWindowInterceptor.IsEnabled)
|
||||
@@ -166,7 +166,7 @@ namespace Ink_Canvas
|
||||
_floatingWindowInterceptorManager.Stop();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
UpdateFloatingWindowInterceptorUI();
|
||||
SaveSettingsToFile();
|
||||
}
|
||||
@@ -304,7 +304,7 @@ namespace Ink_Canvas
|
||||
{
|
||||
_floatingWindowInterceptorManager.SetInterceptRule(type, enabled);
|
||||
}
|
||||
|
||||
|
||||
// 更新设置
|
||||
var ruleName = type.ToString();
|
||||
if (Settings.Automation.FloatingWindowInterceptor.InterceptRules.ContainsKey(ruleName))
|
||||
@@ -342,10 +342,10 @@ namespace Ink_Canvas
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 更新UI显示
|
||||
UpdateFloatingWindowInterceptorUI();
|
||||
|
||||
|
||||
SaveSettingsToFile();
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
||||
@@ -260,7 +260,7 @@ namespace Ink_Canvas
|
||||
|
||||
// 将Bitmap转换为WPF BitmapSource
|
||||
var bitmapSource = ConvertBitmapToBitmapSource(bitmap);
|
||||
|
||||
|
||||
if (bitmapSource == null)
|
||||
{
|
||||
ShowNotification("转换截图失败");
|
||||
@@ -649,7 +649,7 @@ namespace Ink_Canvas
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogHelper.WriteLogToFile($"转换位图失败: {ex.Message}", LogHelper.LogType.Error);
|
||||
|
||||
|
||||
// 尝试使用备用方法:内存流转换
|
||||
try
|
||||
{
|
||||
@@ -658,7 +658,7 @@ namespace Ink_Canvas
|
||||
catch (Exception fallbackEx)
|
||||
{
|
||||
LogHelper.WriteLogToFile($"备用转换方法也失败: {fallbackEx.Message}", LogHelper.LogType.Error);
|
||||
|
||||
|
||||
// 最后尝试:使用最简单的转换方法
|
||||
try
|
||||
{
|
||||
@@ -723,18 +723,18 @@ namespace Ink_Canvas
|
||||
|
||||
// 使用最基础的方法:直接保存为PNG然后加载
|
||||
var tempFile = Path.GetTempFileName() + ".png";
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
bitmap.Save(tempFile, ImageFormat.Png);
|
||||
|
||||
|
||||
var bitmapImage = new BitmapImage();
|
||||
bitmapImage.BeginInit();
|
||||
bitmapImage.UriSource = new Uri(tempFile);
|
||||
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
|
||||
bitmapImage.EndInit();
|
||||
bitmapImage.Freeze();
|
||||
|
||||
|
||||
return bitmapImage;
|
||||
}
|
||||
finally
|
||||
|
||||
@@ -11,6 +11,7 @@ using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Ink;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Threading;
|
||||
using Application = System.Windows.Application;
|
||||
@@ -77,7 +78,7 @@ namespace Ink_Canvas
|
||||
|
||||
#region PPT State Management
|
||||
private bool wasFloatingBarFoldedWhenEnterSlideShow;
|
||||
private bool isEnteredSlideShowEndEvent; //防止重复调用本函数导致墨迹保存失效
|
||||
private bool isEnteredSlideShowEndEvent;
|
||||
private bool isPresentationHaveBlackSpace;
|
||||
|
||||
// 长按翻页相关字段
|
||||
@@ -89,11 +90,11 @@ namespace Ink_Canvas
|
||||
// PowerPoint应用程序守护相关字段
|
||||
private DispatcherTimer _powerPointProcessMonitorTimer;
|
||||
private const int ProcessMonitorInterval = 1000; // 应用程序监控间隔(毫秒)
|
||||
|
||||
|
||||
// 上次播放位置相关字段
|
||||
private int _lastPlaybackPage = 0;
|
||||
private bool _shouldNavigateToLastPage = false;
|
||||
|
||||
|
||||
// 页面切换防抖机制
|
||||
private DateTime _lastSlideSwitchTime = DateTime.MinValue;
|
||||
private int _pendingSlideIndex = -1;
|
||||
@@ -104,10 +105,11 @@ namespace Ink_Canvas
|
||||
#region PPT Managers
|
||||
private PPTManager _pptManager;
|
||||
private MultiPPTInkManager _multiPPTInkManager;
|
||||
private PPTInkManager _singlePPTInkManager;
|
||||
private PPTUIManager _pptUIManager;
|
||||
|
||||
/// <summary>
|
||||
/// 获取PPT管理器实例(供UI管理器使用)
|
||||
/// 获取PPT管理器实例
|
||||
/// </summary>
|
||||
public PPTManager PPTManager => _pptManager;
|
||||
#endregion
|
||||
@@ -133,11 +135,19 @@ namespace Ink_Canvas
|
||||
_pptManager.PresentationClose += OnPPTPresentationClose;
|
||||
_pptManager.SlideShowStateChanged += OnPPTSlideShowStateChanged;
|
||||
|
||||
// 初始化多PPT墨迹管理器
|
||||
_multiPPTInkManager = new MultiPPTInkManager();
|
||||
_multiPPTInkManager.IsAutoSaveEnabled = Settings.PowerPointSettings.IsAutoSaveStrokesInPowerPoint;
|
||||
_multiPPTInkManager.AutoSaveLocation = Settings.Automation.AutoSavedStrokesLocation;
|
||||
_multiPPTInkManager.PPTManager = _pptManager;
|
||||
if (Settings.PowerPointSettings.IsSupportWPS)
|
||||
{
|
||||
_singlePPTInkManager = new PPTInkManager();
|
||||
_singlePPTInkManager.IsAutoSaveEnabled = Settings.PowerPointSettings.IsAutoSaveStrokesInPowerPoint;
|
||||
_singlePPTInkManager.AutoSaveLocation = Settings.Automation.AutoSavedStrokesLocation;
|
||||
}
|
||||
else
|
||||
{
|
||||
_multiPPTInkManager = new MultiPPTInkManager();
|
||||
_multiPPTInkManager.IsAutoSaveEnabled = Settings.PowerPointSettings.IsAutoSaveStrokesInPowerPoint;
|
||||
_multiPPTInkManager.AutoSaveLocation = Settings.Automation.AutoSavedStrokesLocation;
|
||||
_multiPPTInkManager.PPTManager = _pptManager;
|
||||
}
|
||||
|
||||
// 初始化UI管理器
|
||||
_pptUIManager = new PPTUIManager(this);
|
||||
@@ -421,10 +431,12 @@ namespace Ink_Canvas
|
||||
{
|
||||
_pptManager?.Dispose();
|
||||
_multiPPTInkManager?.Dispose();
|
||||
_singlePPTInkManager?.Dispose();
|
||||
_longPressTimer?.Stop();
|
||||
_longPressTimer = null;
|
||||
_pptManager = null;
|
||||
_multiPPTInkManager = null;
|
||||
_singlePPTInkManager = null;
|
||||
_pptUIManager = null;
|
||||
|
||||
// 清理PowerPoint进程守护
|
||||
@@ -509,8 +521,14 @@ namespace Ink_Canvas
|
||||
else
|
||||
{
|
||||
LogHelper.WriteLogToFile("PPT连接已断开", LogHelper.LogType.Event);
|
||||
// 清理墨迹管理器
|
||||
_multiPPTInkManager?.ClearAllStrokes();
|
||||
if (Settings.PowerPointSettings.IsSupportWPS)
|
||||
{
|
||||
_singlePPTInkManager?.ClearAllStrokes();
|
||||
}
|
||||
else
|
||||
{
|
||||
_multiPPTInkManager?.ClearAllStrokes();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -535,8 +553,14 @@ namespace Ink_Canvas
|
||||
TimeMachineHistories[0] = null;
|
||||
}
|
||||
|
||||
// 初始化多PPT墨迹管理器
|
||||
_multiPPTInkManager?.InitializePresentation(pres);
|
||||
if (Settings.PowerPointSettings.IsSupportWPS)
|
||||
{
|
||||
_singlePPTInkManager?.InitializePresentation(pres);
|
||||
}
|
||||
else
|
||||
{
|
||||
_multiPPTInkManager?.InitializePresentation(pres);
|
||||
}
|
||||
|
||||
// 处理跳转到首页或上次播放页的逻辑
|
||||
HandlePresentationOpenNavigation(pres);
|
||||
@@ -570,11 +594,15 @@ namespace Ink_Canvas
|
||||
{
|
||||
Application.Current.Dispatcher.InvokeAsync(() =>
|
||||
{
|
||||
// 保存所有墨迹
|
||||
_multiPPTInkManager?.SaveAllStrokesToFile(pres);
|
||||
|
||||
// 移除演示文稿管理器
|
||||
_multiPPTInkManager?.RemovePresentation(pres);
|
||||
if (Settings.PowerPointSettings.IsSupportWPS)
|
||||
{
|
||||
_singlePPTInkManager?.SaveAllStrokesToFile(pres);
|
||||
}
|
||||
else
|
||||
{
|
||||
_multiPPTInkManager?.SaveAllStrokesToFile(pres);
|
||||
_multiPPTInkManager?.RemovePresentation(pres);
|
||||
}
|
||||
|
||||
_pptUIManager?.UpdateConnectionStatus(false);
|
||||
});
|
||||
@@ -629,7 +657,6 @@ namespace Ink_Canvas
|
||||
}
|
||||
else
|
||||
{
|
||||
// 如果关闭了PPT自动收纳功能,但用户当前在收纳模式下,进入PPT时取消收纳以提供更好的使用体验
|
||||
if (isFloatingBarFolded)
|
||||
{
|
||||
await UnFoldFloatingBar(new object());
|
||||
@@ -640,11 +667,16 @@ namespace Ink_Canvas
|
||||
|
||||
await Application.Current.Dispatcher.InvokeAsync(() =>
|
||||
{
|
||||
// 获取当前活跃的演示文稿并切换到对应的墨迹管理器
|
||||
var activePresentation = _pptManager?.GetCurrentActivePresentation();
|
||||
if (activePresentation != null)
|
||||
{
|
||||
_multiPPTInkManager?.SwitchToPresentation(activePresentation);
|
||||
if (Settings.PowerPointSettings.IsSupportWPS)
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
_multiPPTInkManager?.SwitchToPresentation(activePresentation);
|
||||
}
|
||||
}
|
||||
|
||||
// 处理跳转到首页或上次播放位置
|
||||
@@ -720,6 +752,22 @@ namespace Ink_Canvas
|
||||
{
|
||||
UpdateCurrentToolMode("pen");
|
||||
SetFloatingBarHighlightPosition("pen");
|
||||
if (Settings.Appearance.IsShowQuickColorPalette && QuickColorPalettePanel != null && QuickColorPaletteSingleRowPanel != null)
|
||||
{
|
||||
// 根据显示模式选择显示哪个面板
|
||||
if (Settings.Appearance.QuickColorPaletteDisplayMode == 0)
|
||||
{
|
||||
// 单行显示模式
|
||||
QuickColorPalettePanel.Visibility = Visibility.Collapsed;
|
||||
QuickColorPaletteSingleRowPanel.Visibility = Visibility.Visible;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 双行显示模式
|
||||
QuickColorPalettePanel.Visibility = Visibility.Visible;
|
||||
QuickColorPaletteSingleRowPanel.Visibility = Visibility.Collapsed;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -759,11 +807,16 @@ namespace Ink_Canvas
|
||||
{
|
||||
Application.Current.Dispatcher.InvokeAsync(() =>
|
||||
{
|
||||
// 获取当前活跃的演示文稿并确保切换到正确的墨迹管理器
|
||||
var activePresentation = _pptManager?.GetCurrentActivePresentation();
|
||||
if (activePresentation != null)
|
||||
{
|
||||
_multiPPTInkManager?.SwitchToPresentation(activePresentation);
|
||||
if (Settings.PowerPointSettings.IsSupportWPS)
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
_multiPPTInkManager?.SwitchToPresentation(activePresentation);
|
||||
}
|
||||
}
|
||||
|
||||
var currentSlide = _pptManager?.GetCurrentSlideNumber() ?? 0;
|
||||
@@ -784,7 +837,6 @@ namespace Ink_Canvas
|
||||
{
|
||||
try
|
||||
{
|
||||
// 处理浮动栏状态:根据"退出PPT放映后自动恢复浮动栏状态"设置决定是否恢复
|
||||
if (Settings.Automation.IsAutoFoldAfterPPTSlideShow)
|
||||
{
|
||||
if (wasFloatingBarFoldedWhenEnterSlideShow)
|
||||
@@ -800,15 +852,14 @@ namespace Ink_Canvas
|
||||
{
|
||||
if (Settings.Automation.IsAutoFoldInPPTSlideShow)
|
||||
{
|
||||
if (isFloatingBarFolded)
|
||||
if (isFloatingBarFolded)
|
||||
{
|
||||
await UnFoldFloatingBar(new object());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 如果两个功能都关闭,确保浮动栏展开
|
||||
if (isFloatingBarFolded)
|
||||
if (isFloatingBarFolded)
|
||||
{
|
||||
await UnFoldFloatingBar(new object());
|
||||
}
|
||||
@@ -818,8 +869,14 @@ namespace Ink_Canvas
|
||||
if (isEnteredSlideShowEndEvent) return;
|
||||
isEnteredSlideShowEndEvent = true;
|
||||
|
||||
// 保存所有墨迹
|
||||
if (Settings.PowerPointSettings.IsSupportWPS)
|
||||
{
|
||||
_singlePPTInkManager?.SaveAllStrokesToFile(pres);
|
||||
}
|
||||
else
|
||||
{
|
||||
_multiPPTInkManager?.SaveAllStrokesToFile(pres);
|
||||
}
|
||||
|
||||
await Application.Current.Dispatcher.InvokeAsync(() =>
|
||||
{
|
||||
@@ -879,6 +936,9 @@ namespace Ink_Canvas
|
||||
if (GridTransparencyFakeBackground.Background != Brushes.Transparent)
|
||||
BtnHideInkCanvas_Click(BtnHideInkCanvas, null);
|
||||
SetCurrentToolMode(InkCanvasEditingMode.None);
|
||||
|
||||
UpdateCurrentToolMode("cursor");
|
||||
SetFloatingBarHighlightPosition("cursor");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -889,8 +949,6 @@ namespace Ink_Canvas
|
||||
await Task.Delay(100);
|
||||
await Application.Current.Dispatcher.InvokeAsync(() =>
|
||||
{
|
||||
// 强制重新计算浮动栏位置,确保在退出PPT模式后正确复位
|
||||
// 先调用桌面模式的复位方法,然后调用通用的位置计算方法
|
||||
PureViewboxFloatingBarMarginAnimationInDesktopMode();
|
||||
ViewboxFloatingBarMarginAnimation(100, true);
|
||||
});
|
||||
@@ -941,7 +999,24 @@ namespace Ink_Canvas
|
||||
_lastPlaybackPage = page;
|
||||
new YesOrNoNotificationWindow($"上次播放到了第 {page} 页, 是否立即跳转", () =>
|
||||
{
|
||||
_shouldNavigateToLastPage = true;
|
||||
try
|
||||
{
|
||||
if (_pptManager?.PPTApplication != null)
|
||||
{
|
||||
if (_pptManager.PPTApplication.SlideShowWindows.Count >= 1)
|
||||
{
|
||||
pres.SlideShowWindow.View.GotoSlide(page);
|
||||
}
|
||||
else
|
||||
{
|
||||
pres.Windows[1].View.GotoSlide(page);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogHelper.WriteLogToFile($"跳转到第{page}页失败: {ex}", LogHelper.LogType.Error);
|
||||
}
|
||||
}).ShowDialog();
|
||||
}
|
||||
}
|
||||
@@ -1060,7 +1135,16 @@ namespace Ink_Canvas
|
||||
{
|
||||
try
|
||||
{
|
||||
var strokes = _multiPPTInkManager?.LoadSlideStrokes(slideIndex);
|
||||
StrokeCollection strokes = null;
|
||||
if (Settings.PowerPointSettings.IsSupportWPS)
|
||||
{
|
||||
strokes = _singlePPTInkManager?.LoadSlideStrokes(slideIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
strokes = _multiPPTInkManager?.LoadSlideStrokes(slideIndex);
|
||||
}
|
||||
|
||||
if (strokes != null)
|
||||
{
|
||||
inkCanvas.Strokes.Clear();
|
||||
@@ -1080,15 +1164,18 @@ namespace Ink_Canvas
|
||||
{
|
||||
try
|
||||
{
|
||||
// 获取当前活跃的演示文稿
|
||||
var activePresentation = _pptManager?.GetCurrentActivePresentation();
|
||||
if (activePresentation != null)
|
||||
if (Settings.PowerPointSettings.IsSupportWPS)
|
||||
{
|
||||
// 切换到对应的墨迹管理器
|
||||
_multiPPTInkManager?.SwitchToPresentation(activePresentation);
|
||||
|
||||
// 重置锁定状态
|
||||
_multiPPTInkManager?.ResetCurrentPresentationLockState();
|
||||
_singlePPTInkManager?.ResetLockState();
|
||||
}
|
||||
else
|
||||
{
|
||||
var activePresentation = _pptManager?.GetCurrentActivePresentation();
|
||||
if (activePresentation != null)
|
||||
{
|
||||
_multiPPTInkManager?.SwitchToPresentation(activePresentation);
|
||||
_multiPPTInkManager?.ResetCurrentPresentationLockState();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -1106,21 +1193,21 @@ namespace Ink_Canvas
|
||||
{
|
||||
// 重置进入PPT时的浮动栏收纳状态记录
|
||||
wasFloatingBarFoldedWhenEnterSlideShow = false;
|
||||
|
||||
|
||||
// 重置PPT放映结束事件标志
|
||||
isEnteredSlideShowEndEvent = false;
|
||||
|
||||
|
||||
// 重置演示文稿黑边状态
|
||||
isPresentationHaveBlackSpace = false;
|
||||
|
||||
|
||||
// 重置上次播放位置相关字段
|
||||
_lastPlaybackPage = 0;
|
||||
_shouldNavigateToLastPage = false;
|
||||
|
||||
|
||||
// 重置页面切换防抖机制
|
||||
_lastSlideSwitchTime = DateTime.MinValue;
|
||||
_pendingSlideIndex = -1;
|
||||
|
||||
|
||||
LogHelper.WriteLogToFile("PPT状态变量已重置", LogHelper.LogType.Trace);
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -1137,15 +1224,15 @@ namespace Ink_Canvas
|
||||
try
|
||||
{
|
||||
var now = DateTime.Now;
|
||||
|
||||
|
||||
// 如果距离上次切换时间太短,使用防抖机制
|
||||
if (now - _lastSlideSwitchTime < TimeSpan.FromMilliseconds(SlideSwitchDebounceMs))
|
||||
{
|
||||
_pendingSlideIndex = currentSlide;
|
||||
|
||||
|
||||
// 停止之前的定时器
|
||||
_slideSwitchDebounceTimer?.Stop();
|
||||
|
||||
|
||||
// 创建新的定时器
|
||||
_slideSwitchDebounceTimer = new System.Timers.Timer(SlideSwitchDebounceMs);
|
||||
_slideSwitchDebounceTimer.Elapsed += (sender, e) =>
|
||||
@@ -1169,7 +1256,7 @@ namespace Ink_Canvas
|
||||
SwitchSlideInk(currentSlide);
|
||||
_pptUIManager?.UpdateCurrentSlideNumber(currentSlide, totalSlides);
|
||||
}
|
||||
|
||||
|
||||
_lastSlideSwitchTime = now;
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -1190,38 +1277,53 @@ namespace Ink_Canvas
|
||||
|
||||
// 获取当前页面索引
|
||||
var currentSlideIndex = _pptManager?.GetCurrentSlideNumber() ?? 0;
|
||||
|
||||
|
||||
|
||||
|
||||
// 验证页面索引的有效性
|
||||
if (newSlideIndex <= 0)
|
||||
{
|
||||
LogHelper.WriteLogToFile($"无效的新页面索引: {newSlideIndex},跳过页面切换", LogHelper.LogType.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// 如果有当前墨迹且不是第一次切换,先保存到当前页面
|
||||
if (inkCanvas.Strokes.Count > 0 && currentSlideIndex > 0 && currentSlideIndex != newSlideIndex)
|
||||
{
|
||||
// 检查是否可以写入墨迹
|
||||
bool canWrite = _multiPPTInkManager?.CanWriteInk(currentSlideIndex) == true;
|
||||
|
||||
if (canWrite)
|
||||
bool canWrite = false;
|
||||
if (Settings.PowerPointSettings.IsSupportWPS)
|
||||
{
|
||||
// 正常保存
|
||||
_multiPPTInkManager?.SaveCurrentSlideStrokes(currentSlideIndex, inkCanvas.Strokes);
|
||||
canWrite = _singlePPTInkManager?.CanWriteInk(currentSlideIndex) == true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 墨迹被锁定,跳过保存以避免墨迹错页
|
||||
canWrite = _multiPPTInkManager?.CanWriteInk(currentSlideIndex) == true;
|
||||
}
|
||||
|
||||
if (canWrite)
|
||||
{
|
||||
if (Settings.PowerPointSettings.IsSupportWPS)
|
||||
{
|
||||
_singlePPTInkManager?.SaveCurrentSlideStrokes(currentSlideIndex, inkCanvas.Strokes);
|
||||
}
|
||||
else
|
||||
{
|
||||
_multiPPTInkManager?.SaveCurrentSlideStrokes(currentSlideIndex, inkCanvas.Strokes);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (inkCanvas.Strokes.Count > 0 && currentSlideIndex <= 0)
|
||||
{
|
||||
// 无法获取当前页面索引时,不保存墨迹,直接清空
|
||||
}
|
||||
|
||||
// 切换到新页面并加载墨迹
|
||||
var newStrokes = _multiPPTInkManager?.SwitchToSlide(newSlideIndex, null);
|
||||
|
||||
StrokeCollection newStrokes = null;
|
||||
if (Settings.PowerPointSettings.IsSupportWPS)
|
||||
{
|
||||
newStrokes = _singlePPTInkManager?.SwitchToSlide(newSlideIndex, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
newStrokes = _multiPPTInkManager?.SwitchToSlide(newSlideIndex, null);
|
||||
}
|
||||
if (newStrokes != null)
|
||||
{
|
||||
inkCanvas.Strokes.Clear();
|
||||
@@ -1362,7 +1464,14 @@ namespace Ink_Canvas
|
||||
var currentSlide = _pptManager?.GetCurrentSlideNumber() ?? 0;
|
||||
if (currentSlide > 0)
|
||||
{
|
||||
_multiPPTInkManager?.SaveCurrentSlideStrokes(currentSlide, inkCanvas.Strokes);
|
||||
if (Settings.PowerPointSettings.IsSupportWPS)
|
||||
{
|
||||
_singlePPTInkManager?.SaveCurrentSlideStrokes(currentSlide, inkCanvas.Strokes);
|
||||
}
|
||||
else
|
||||
{
|
||||
_multiPPTInkManager?.SaveCurrentSlideStrokes(currentSlide, inkCanvas.Strokes);
|
||||
}
|
||||
}
|
||||
|
||||
// 保存截图(如果启用)
|
||||
@@ -1402,7 +1511,14 @@ namespace Ink_Canvas
|
||||
var currentSlide = _pptManager?.GetCurrentSlideNumber() ?? 0;
|
||||
if (currentSlide > 0)
|
||||
{
|
||||
_multiPPTInkManager?.SaveCurrentSlideStrokes(currentSlide, inkCanvas.Strokes);
|
||||
if (Settings.PowerPointSettings.IsSupportWPS)
|
||||
{
|
||||
_singlePPTInkManager?.SaveCurrentSlideStrokes(currentSlide, inkCanvas.Strokes);
|
||||
}
|
||||
else
|
||||
{
|
||||
_multiPPTInkManager?.SaveCurrentSlideStrokes(currentSlide, inkCanvas.Strokes);
|
||||
}
|
||||
}
|
||||
|
||||
// 保存截图(如果启用)
|
||||
@@ -1432,7 +1548,7 @@ namespace Ink_Canvas
|
||||
});
|
||||
}
|
||||
|
||||
private async void PPTNavigationBtn_MouseDown(object sender, MouseButtonEventArgs e)
|
||||
private void PPTNavigationBtn_MouseDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
lastBorderMouseDownObject = sender;
|
||||
if (!Settings.PowerPointSettings.EnablePPTButtonPageClickable) return;
|
||||
@@ -1454,7 +1570,7 @@ namespace Ink_Canvas
|
||||
}
|
||||
}
|
||||
|
||||
private async void PPTNavigationBtn_MouseLeave(object sender, MouseEventArgs e)
|
||||
private void PPTNavigationBtn_MouseLeave(object sender, MouseEventArgs e)
|
||||
{
|
||||
lastBorderMouseDownObject = null;
|
||||
if (sender == PPTLSPageButton)
|
||||
@@ -1562,7 +1678,14 @@ namespace Ink_Canvas
|
||||
{
|
||||
Application.Current.Dispatcher.Invoke(() =>
|
||||
{
|
||||
_multiPPTInkManager?.SaveCurrentSlideStrokes(currentSlide, inkCanvas.Strokes);
|
||||
if (Settings.PowerPointSettings.IsSupportWPS)
|
||||
{
|
||||
_singlePPTInkManager?.SaveCurrentSlideStrokes(currentSlide, inkCanvas.Strokes);
|
||||
}
|
||||
else
|
||||
{
|
||||
_multiPPTInkManager?.SaveCurrentSlideStrokes(currentSlide, inkCanvas.Strokes);
|
||||
}
|
||||
timeMachine.ClearStrokeHistory();
|
||||
});
|
||||
}
|
||||
@@ -1590,7 +1713,7 @@ namespace Ink_Canvas
|
||||
|
||||
HideSubPanels("cursor");
|
||||
SetCurrentToolMode(InkCanvasEditingMode.None);
|
||||
|
||||
|
||||
await Task.Delay(150);
|
||||
if (Settings.Automation.IsAutoFoldAfterPPTSlideShow)
|
||||
{
|
||||
@@ -1628,7 +1751,7 @@ namespace Ink_Canvas
|
||||
|
||||
// 异常情况下也手动处理收纳状态恢复
|
||||
await HandleManualSlideShowEnd();
|
||||
|
||||
|
||||
// 异常情况下也要根据设置决定浮动栏边距
|
||||
await Task.Delay(150);
|
||||
if (Settings.Automation.IsAutoFoldAfterPPTSlideShow)
|
||||
@@ -1678,7 +1801,7 @@ namespace Ink_Canvas
|
||||
{
|
||||
if (Settings.Automation.IsAutoFoldInPPTSlideShow)
|
||||
{
|
||||
if (isFloatingBarFolded)
|
||||
if (isFloatingBarFolded)
|
||||
{
|
||||
await UnFoldFloatingBar(new object());
|
||||
}
|
||||
@@ -1686,7 +1809,7 @@ namespace Ink_Canvas
|
||||
else
|
||||
{
|
||||
// 如果两个功能都关闭,确保浮动栏展开
|
||||
if (isFloatingBarFolded)
|
||||
if (isFloatingBarFolded)
|
||||
{
|
||||
await UnFoldFloatingBar(new object());
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@ namespace Ink_Canvas
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
var tarPos = transform.Transform(point);
|
||||
scrollViewer.ScrollToVerticalOffset(tarPos.Y);
|
||||
}
|
||||
|
||||
@@ -347,52 +347,76 @@ namespace Ink_Canvas
|
||||
FloatingbarHeadIconImg.Margin = new Thickness(0.5);
|
||||
}
|
||||
else if (index == 1)
|
||||
{
|
||||
FloatingbarHeadIconImg.Source =
|
||||
new BitmapImage(new Uri("pack://application:,,,/Resources/Icons-png/icc-noshadow.png"));
|
||||
FloatingbarHeadIconImg.Margin = new Thickness(0.5);
|
||||
}
|
||||
else if (index == 2)
|
||||
{
|
||||
FloatingbarHeadIconImg.Source =
|
||||
new BitmapImage(new Uri("pack://application:,,,/Resources/Icons-png/icc-dark.png"));
|
||||
FloatingbarHeadIconImg.Margin = new Thickness(0.5);
|
||||
}
|
||||
else if (index == 3)
|
||||
{
|
||||
FloatingbarHeadIconImg.Source =
|
||||
new BitmapImage(new Uri("pack://application:,,,/Resources/Icons-png/icc-sharpdark.png"));
|
||||
FloatingbarHeadIconImg.Margin = new Thickness(0.5);
|
||||
}
|
||||
else if (index == 4)
|
||||
{
|
||||
FloatingbarHeadIconImg.Source =
|
||||
new BitmapImage(new Uri("pack://application:,,,/Resources/Icons-png/icc-transparent-light-small.png"));
|
||||
FloatingbarHeadIconImg.Margin = new Thickness(0.5);
|
||||
}
|
||||
else if (index == 5)
|
||||
{
|
||||
FloatingbarHeadIconImg.Source =
|
||||
new BitmapImage(
|
||||
new Uri("pack://application:,,,/Resources/Icons-png/icc-transparent-dark-small.png"));
|
||||
FloatingbarHeadIconImg.Margin = new Thickness(1.2);
|
||||
}
|
||||
else if (index == 2)
|
||||
else if (index == 6)
|
||||
{
|
||||
FloatingbarHeadIconImg.Source =
|
||||
new BitmapImage(new Uri("pack://application:,,,/Resources/Icons-png/kuandoujiyanhuaji.png"));
|
||||
FloatingbarHeadIconImg.Margin = new Thickness(2, 2, 2, 1.5);
|
||||
}
|
||||
else if (index == 3)
|
||||
else if (index == 7)
|
||||
{
|
||||
FloatingbarHeadIconImg.Source =
|
||||
new BitmapImage(new Uri("pack://application:,,,/Resources/Icons-png/kuanshounvhuaji.png"));
|
||||
FloatingbarHeadIconImg.Margin = new Thickness(2, 2, 2, 1.5);
|
||||
}
|
||||
else if (index == 4)
|
||||
else if (index == 8)
|
||||
{
|
||||
FloatingbarHeadIconImg.Source =
|
||||
new BitmapImage(new Uri("pack://application:,,,/Resources/Icons-png/kuanciya.png"));
|
||||
FloatingbarHeadIconImg.Margin = new Thickness(2, 2, 2, 1.5);
|
||||
}
|
||||
else if (index == 5)
|
||||
else if (index == 9)
|
||||
{
|
||||
FloatingbarHeadIconImg.Source =
|
||||
new BitmapImage(new Uri("pack://application:,,,/Resources/Icons-png/kuanneikuhuaji.png"));
|
||||
FloatingbarHeadIconImg.Margin = new Thickness(2, 2, 2, 1.5);
|
||||
}
|
||||
else if (index == 6)
|
||||
else if (index == 10)
|
||||
{
|
||||
FloatingbarHeadIconImg.Source =
|
||||
new BitmapImage(new Uri("pack://application:,,,/Resources/Icons-png/kuandogeyuanliangwo.png"));
|
||||
FloatingbarHeadIconImg.Margin = new Thickness(2, 2, 2, 1.5);
|
||||
}
|
||||
else if (index == 7)
|
||||
else if (index == 11)
|
||||
{
|
||||
FloatingbarHeadIconImg.Source =
|
||||
new BitmapImage(new Uri("pack://application:,,,/Resources/Icons-png/tiebahuaji.png"));
|
||||
FloatingbarHeadIconImg.Margin = new Thickness(2, 2, 2, 1);
|
||||
}
|
||||
else if (index >= 8 && index - 8 < Settings.Appearance.CustomFloatingBarImgs.Count)
|
||||
else if (index >= 12 && index - 12 < Settings.Appearance.CustomFloatingBarImgs.Count)
|
||||
{
|
||||
// 使用自定义图标
|
||||
var customIcon = Settings.Appearance.CustomFloatingBarImgs[index - 8];
|
||||
var customIcon = Settings.Appearance.CustomFloatingBarImgs[index - 12];
|
||||
try
|
||||
{
|
||||
FloatingbarHeadIconImg.Source = new BitmapImage(new Uri(customIcon.FilePath));
|
||||
@@ -409,8 +433,8 @@ namespace Ink_Canvas
|
||||
|
||||
public void UpdateCustomIconsInComboBox()
|
||||
{
|
||||
// 保留前8个内置图标选项
|
||||
while (ComboBoxFloatingBarImg.Items.Count > 8)
|
||||
// 保留前12个内置图标选项
|
||||
while (ComboBoxFloatingBarImg.Items.Count > 12)
|
||||
{
|
||||
ComboBoxFloatingBarImg.Items.RemoveAt(ComboBoxFloatingBarImg.Items.Count - 1);
|
||||
}
|
||||
@@ -1014,23 +1038,73 @@ namespace Ink_Canvas
|
||||
PPTBtnPreviewRS.Visibility = Visibility.Collapsed;
|
||||
}
|
||||
|
||||
// 计算预览区域的缩放比例
|
||||
double previewScaleY = 182.0 / SystemParameters.PrimaryScreenHeight;
|
||||
double previewScaleX = 324.0 / SystemParameters.PrimaryScreenWidth;
|
||||
|
||||
double sideButtonScaleFactor = 1.9;
|
||||
|
||||
// 获取当前屏幕的实际尺寸(考虑DPI缩放)
|
||||
var actualScreenWidth = SystemParameters.PrimaryScreenWidth;
|
||||
var actualScreenHeight = SystemParameters.PrimaryScreenHeight;
|
||||
|
||||
// 预览区域固定尺寸
|
||||
const double previewWidth = 324.0;
|
||||
const double previewHeight = 182.0;
|
||||
|
||||
// 计算缩放比例(预览区域与实际屏幕的比例)
|
||||
double scaleX = previewWidth / actualScreenWidth;
|
||||
double scaleY = previewHeight / actualScreenHeight;
|
||||
|
||||
// 获取按钮位置设置
|
||||
double rsPosition = Settings.PowerPointSettings.PPTRSButtonPosition;
|
||||
double lsPosition = Settings.PowerPointSettings.PPTLSButtonPosition;
|
||||
|
||||
PPTBtnPreviewRSTransform.Y = -(rsPosition * 2 * previewScaleY / sideButtonScaleFactor);
|
||||
PPTBtnPreviewLSTransform.Y = -(lsPosition * 2 * previewScaleY / sideButtonScaleFactor);
|
||||
double lbPosition = Settings.PowerPointSettings.PPTLBButtonPosition;
|
||||
double rbPosition = Settings.PowerPointSettings.PPTRBButtonPosition;
|
||||
|
||||
bool showSidePageButton = sopt.Length >= 1 && sopt[0] == '2';
|
||||
bool showBottomPageButton = bopt.Length >= 1 && bopt[0] == '2';
|
||||
|
||||
double bottomButtonScaleFactor = 1.2;
|
||||
double leftMarginOffset = 6 * previewScaleX;
|
||||
PPTBtnPreviewLBTransform.X = leftMarginOffset + (Settings.PowerPointSettings.PPTLBButtonPosition * previewScaleX / bottomButtonScaleFactor);
|
||||
PPTBtnPreviewRBTransform.X = -(leftMarginOffset + (Settings.PowerPointSettings.PPTRBButtonPosition * previewScaleX / bottomButtonScaleFactor));
|
||||
// 页码按钮的实际尺寸
|
||||
const double pageButtonWidth = 50.0;
|
||||
const double pageButtonHeight = 50.0;
|
||||
|
||||
// 计算侧边按钮位置(Y轴偏移)
|
||||
double sideOffsetY = showSidePageButton ? pageButtonHeight * scaleY : 0;
|
||||
PPTBtnPreviewRSTransform.Y = -(rsPosition * scaleY) - sideOffsetY;
|
||||
PPTBtnPreviewLSTransform.Y = -(lsPosition * scaleY) - sideOffsetY;
|
||||
|
||||
// 计算底部按钮位置(X轴偏移)
|
||||
const double bottomMarginOffset = 6.0;
|
||||
double scaledMarginOffset = bottomMarginOffset * scaleX;
|
||||
|
||||
double bottomOffsetX = showBottomPageButton ? pageButtonWidth * scaleX : 0;
|
||||
PPTBtnPreviewLBTransform.X = scaledMarginOffset + (lbPosition * scaleX) + bottomOffsetX;
|
||||
PPTBtnPreviewRBTransform.X = -(scaledMarginOffset + (rbPosition * scaleX) + bottomOffsetX);
|
||||
|
||||
// 计算工具栏尺寸
|
||||
var dpiScaleX = 1.0;
|
||||
var dpiScaleY = 1.0;
|
||||
try
|
||||
{
|
||||
var source = PresentationSource.FromVisual(this);
|
||||
if (source?.CompositionTarget != null)
|
||||
{
|
||||
var transform = source.CompositionTarget.TransformToDevice;
|
||||
dpiScaleX = transform.M11;
|
||||
dpiScaleY = transform.M22;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
dpiScaleX = 1.0;
|
||||
dpiScaleY = 1.0;
|
||||
}
|
||||
|
||||
// 计算工具栏的实际尺寸
|
||||
const double baseToolbarHeight = 24.0;
|
||||
|
||||
double actualToolbarHeight = baseToolbarHeight * dpiScaleY;
|
||||
double scaledToolbarHeight = actualToolbarHeight * scaleY;
|
||||
double scaledToolbarWidth = previewWidth;
|
||||
|
||||
// 设置工具栏尺寸
|
||||
PPTBtnPreviewToolbar.Height = scaledToolbarHeight;
|
||||
PPTBtnPreviewToolbar.Width = scaledToolbarWidth;
|
||||
}
|
||||
|
||||
private void ToggleSwitchShowCursor_Toggled(object sender, RoutedEventArgs e)
|
||||
@@ -1064,6 +1138,7 @@ namespace Ink_Canvas
|
||||
if (!isLoaded) return;
|
||||
|
||||
Settings.Canvas.DisablePressure = ToggleSwitchDisablePressure.IsOn;
|
||||
inkCanvas.DefaultDrawingAttributes.IgnorePressure = Settings.Canvas.DisablePressure;
|
||||
|
||||
// 如果启用了屏蔽压感,则自动关闭压感触屏模式
|
||||
if (Settings.Canvas.DisablePressure && Settings.Canvas.EnablePressureTouchMode)
|
||||
@@ -1432,18 +1507,18 @@ namespace Ink_Canvas
|
||||
private void ToggleSwitchAutoFoldInPPTSlideShow_Toggled(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (!isLoaded) return;
|
||||
|
||||
|
||||
// 记录设置变更前的状态
|
||||
bool previousState = Settings.Automation.IsAutoFoldInPPTSlideShow;
|
||||
Settings.Automation.IsAutoFoldInPPTSlideShow = ToggleSwitchAutoFoldInPPTSlideShow.IsOn;
|
||||
|
||||
|
||||
// 如果设置状态发生变化,重置PPT相关状态变量
|
||||
if (previousState != Settings.Automation.IsAutoFoldInPPTSlideShow)
|
||||
{
|
||||
ResetPPTStateVariables();
|
||||
LogHelper.WriteLogToFile($"PPT自动收纳设置已变更: {Settings.Automation.IsAutoFoldInPPTSlideShow}, 已重置相关状态变量", LogHelper.LogType.Trace);
|
||||
}
|
||||
|
||||
|
||||
if (Settings.Automation.IsAutoFoldInPPTSlideShow)
|
||||
{
|
||||
SettingsPPTInkingAndAutoFoldExplictBorder.Visibility = Visibility.Visible;
|
||||
@@ -1802,6 +1877,29 @@ namespace Ink_Canvas
|
||||
SaveSettingsToFile();
|
||||
}
|
||||
|
||||
private void ToggleSwitchEnableAutoSaveStrokes_Toggled(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (!isLoaded) return;
|
||||
Settings.Automation.IsEnableAutoSaveStrokes = ToggleSwitchEnableAutoSaveStrokes.IsOn;
|
||||
SaveSettingsToFile();
|
||||
// 更新定时器状态
|
||||
UpdateAutoSaveStrokesTimer();
|
||||
}
|
||||
|
||||
private void ComboBoxAutoSaveStrokesInterval_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
if (!isLoaded || ComboBoxAutoSaveStrokesInterval.SelectedItem == null) return;
|
||||
|
||||
var selectedItem = ComboBoxAutoSaveStrokesInterval.SelectedItem as System.Windows.Controls.ComboBoxItem;
|
||||
if (selectedItem?.Tag != null && int.TryParse(selectedItem.Tag.ToString(), out int intervalMinutes))
|
||||
{
|
||||
Settings.Automation.AutoSaveStrokesIntervalMinutes = intervalMinutes;
|
||||
SaveSettingsToFile();
|
||||
// 更新定时器间隔
|
||||
UpdateAutoSaveStrokesTimer();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Gesture
|
||||
@@ -1824,7 +1922,7 @@ namespace Ink_Canvas
|
||||
private void ToggleSwitchEnableTwoFingerZoom_Toggled(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (!isLoaded) return;
|
||||
|
||||
|
||||
// 如果多指书写模式启用,强制禁用双指手势
|
||||
if (ToggleSwitchEnableMultiTouchMode.IsOn)
|
||||
{
|
||||
@@ -1835,7 +1933,7 @@ namespace Ink_Canvas
|
||||
SaveSettingsToFile();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (sender == ToggleSwitchEnableTwoFingerZoom)
|
||||
BoardToggleSwitchEnableTwoFingerZoom.IsOn = ToggleSwitchEnableTwoFingerZoom.IsOn;
|
||||
else
|
||||
@@ -1915,7 +2013,7 @@ namespace Ink_Canvas
|
||||
}
|
||||
|
||||
Settings.Gesture.IsEnableMultiTouchMode = ToggleSwitchEnableMultiTouchMode.IsOn;
|
||||
|
||||
|
||||
// 如果启用多指书写模式,强制禁用所有双指手势
|
||||
if (ToggleSwitchEnableMultiTouchMode.IsOn)
|
||||
{
|
||||
@@ -1940,7 +2038,7 @@ namespace Ink_Canvas
|
||||
if (BoardToggleSwitchEnableTwoFingerRotation != null)
|
||||
BoardToggleSwitchEnableTwoFingerRotation.IsOn = false;
|
||||
}
|
||||
|
||||
|
||||
CheckEnableTwoFingerGestureBtnColorPrompt();
|
||||
SaveSettingsToFile();
|
||||
}
|
||||
@@ -1948,7 +2046,7 @@ namespace Ink_Canvas
|
||||
private void ToggleSwitchEnableTwoFingerTranslate_Toggled(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (!isLoaded) return;
|
||||
|
||||
|
||||
// 如果多指书写模式启用,强制禁用双指手势
|
||||
if (ToggleSwitchEnableMultiTouchMode.IsOn)
|
||||
{
|
||||
@@ -1959,7 +2057,7 @@ namespace Ink_Canvas
|
||||
SaveSettingsToFile();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (sender == ToggleSwitchEnableTwoFingerTranslate)
|
||||
BoardToggleSwitchEnableTwoFingerTranslate.IsOn = ToggleSwitchEnableTwoFingerTranslate.IsOn;
|
||||
else
|
||||
@@ -2534,6 +2632,51 @@ namespace Ink_Canvas
|
||||
{
|
||||
if (!isLoaded) return;
|
||||
Settings.RandSettings.UseLegacyTimerUI = ToggleSwitchUseLegacyTimerUI.IsOn;
|
||||
if (ToggleSwitchUseLegacyTimerUI.IsOn)
|
||||
{
|
||||
ToggleSwitchUseNewStyleUI.IsOn = false;
|
||||
Settings.RandSettings.UseNewStyleUI = false;
|
||||
}
|
||||
SaveSettingsToFile();
|
||||
}
|
||||
|
||||
private void ToggleSwitchUseNewStyleUI_Toggled(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (!isLoaded) return;
|
||||
Settings.RandSettings.UseNewStyleUI = ToggleSwitchUseNewStyleUI.IsOn;
|
||||
if (ToggleSwitchUseNewStyleUI.IsOn)
|
||||
{
|
||||
ToggleSwitchUseLegacyTimerUI.IsOn = false;
|
||||
Settings.RandSettings.UseLegacyTimerUI = false;
|
||||
}
|
||||
SaveSettingsToFile();
|
||||
}
|
||||
|
||||
private void ToggleSwitchEnableOvertimeCountUp_Toggled(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (!isLoaded) return;
|
||||
Settings.RandSettings.EnableOvertimeCountUp = ToggleSwitchEnableOvertimeCountUp.IsOn;
|
||||
|
||||
if (!ToggleSwitchEnableOvertimeCountUp.IsOn)
|
||||
{
|
||||
ToggleSwitchEnableOvertimeRedText.IsOn = false;
|
||||
Settings.RandSettings.EnableOvertimeRedText = false;
|
||||
}
|
||||
|
||||
SaveSettingsToFile();
|
||||
}
|
||||
|
||||
private void ToggleSwitchEnableOvertimeRedText_Toggled(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (!isLoaded) return;
|
||||
|
||||
if (ToggleSwitchEnableOvertimeRedText.IsOn && !ToggleSwitchEnableOvertimeCountUp.IsOn)
|
||||
{
|
||||
ToggleSwitchEnableOvertimeRedText.IsOn = false;
|
||||
return;
|
||||
}
|
||||
|
||||
Settings.RandSettings.EnableOvertimeRedText = ToggleSwitchEnableOvertimeRedText.IsOn;
|
||||
SaveSettingsToFile();
|
||||
}
|
||||
|
||||
@@ -2544,6 +2687,71 @@ namespace Ink_Canvas
|
||||
SaveSettingsToFile();
|
||||
}
|
||||
|
||||
private void ToggleSwitchEnableProgressiveReminder_Toggled(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (!isLoaded) return;
|
||||
Settings.RandSettings.EnableProgressiveReminder = ToggleSwitchEnableProgressiveReminder.IsOn;
|
||||
SaveSettingsToFile();
|
||||
}
|
||||
|
||||
// 新点名UI设置事件处理
|
||||
private void ToggleSwitchUseNewRollCallUI_Toggled(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (!isLoaded) return;
|
||||
Settings.RandSettings.UseNewRollCallUI = ToggleSwitchUseNewRollCallUI.IsOn;
|
||||
SaveSettingsToFile();
|
||||
}
|
||||
|
||||
private void ToggleSwitchEnableMLAvoidance_Toggled(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (!isLoaded) return;
|
||||
Settings.RandSettings.EnableMLAvoidance = ToggleSwitchEnableMLAvoidance.IsOn;
|
||||
SaveSettingsToFile();
|
||||
}
|
||||
|
||||
private void MLAvoidanceHistorySlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
|
||||
{
|
||||
if (!isLoaded) return;
|
||||
Settings.RandSettings.MLAvoidanceHistoryCount = (int)MLAvoidanceHistorySlider.Value;
|
||||
SaveSettingsToFile();
|
||||
}
|
||||
|
||||
private void MLAvoidanceWeightSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
|
||||
{
|
||||
if (!isLoaded) return;
|
||||
Settings.RandSettings.MLAvoidanceWeight = MLAvoidanceWeightSlider.Value;
|
||||
SaveSettingsToFile();
|
||||
}
|
||||
|
||||
private void ProgressiveReminderVolumeSlider_ValueChanged(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (!isLoaded) return;
|
||||
Settings.RandSettings.ProgressiveReminderVolume = ProgressiveReminderVolumeSlider.Value;
|
||||
SaveSettingsToFile();
|
||||
}
|
||||
|
||||
private void ButtonSelectCustomProgressiveReminderSound_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Microsoft.Win32.OpenFileDialog openFileDialog = new Microsoft.Win32.OpenFileDialog
|
||||
{
|
||||
Title = "选择渐进提醒音频文件",
|
||||
Filter = "音频文件 (*.wav)|*.wav|所有文件 (*.*)|*.*",
|
||||
DefaultExt = "wav"
|
||||
};
|
||||
|
||||
if (openFileDialog.ShowDialog() == true)
|
||||
{
|
||||
Settings.RandSettings.ProgressiveReminderSoundPath = openFileDialog.FileName;
|
||||
SaveSettingsToFile();
|
||||
}
|
||||
}
|
||||
|
||||
private void ButtonResetProgressiveReminderSound_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Settings.RandSettings.ProgressiveReminderSoundPath = "";
|
||||
SaveSettingsToFile();
|
||||
}
|
||||
|
||||
private void ButtonSelectCustomTimerSound_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Microsoft.Win32.OpenFileDialog openFileDialog = new Microsoft.Win32.OpenFileDialog
|
||||
@@ -2584,6 +2792,20 @@ namespace Ink_Canvas
|
||||
SaveSettingsToFile();
|
||||
}
|
||||
|
||||
private void ToggleSwitchEnableQuickDraw_Toggled(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (!isLoaded) return;
|
||||
|
||||
// 获取开关状态并保存到设置中
|
||||
Settings.RandSettings.EnableQuickDraw = ToggleSwitchEnableQuickDraw.IsOn;
|
||||
|
||||
// 保存设置到文件
|
||||
SaveSettingsToFile();
|
||||
|
||||
// 根据设置状态显示或隐藏快抽悬浮按钮
|
||||
ShowQuickDrawFloatingButton();
|
||||
}
|
||||
|
||||
private void ToggleSwitchExternalCaller_Toggled(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (!isLoaded) return;
|
||||
@@ -3011,7 +3233,7 @@ namespace Ink_Canvas
|
||||
{
|
||||
Directory.CreateDirectory(configsDir);
|
||||
}
|
||||
|
||||
|
||||
File.WriteAllText(App.RootPath + settingsFileName, text);
|
||||
}
|
||||
catch { }
|
||||
@@ -3063,6 +3285,7 @@ namespace Ink_Canvas
|
||||
if (Settings.Startup.IsAutoUpdate)
|
||||
{
|
||||
LogHelper.WriteLogToFile($"AutoUpdate | Channel changed to {newChannel}, performing immediate update check");
|
||||
ResetUpdateCheckRetry();
|
||||
|
||||
// 执行完整的更新检查
|
||||
await Task.Run(async () =>
|
||||
@@ -3088,6 +3311,149 @@ namespace Ink_Canvas
|
||||
}
|
||||
}
|
||||
|
||||
private async void ManualUpdateButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
ManualUpdateButton.IsEnabled = false;
|
||||
ManualUpdateButton.Content = "正在检查更新...";
|
||||
|
||||
try
|
||||
{
|
||||
LogHelper.WriteLogToFile("ManualUpdate | Manual update button clicked");
|
||||
|
||||
// 使用当前选择的更新通道检查更新
|
||||
var (remoteVersion, lineGroup, apiReleaseNotes) = await AutoUpdateHelper.CheckForUpdates(Settings.Startup.UpdateChannel, true, false);
|
||||
|
||||
if (remoteVersion != null)
|
||||
{
|
||||
LogHelper.WriteLogToFile($"ManualUpdate | Found new version: {remoteVersion}");
|
||||
|
||||
// 获取当前版本
|
||||
string currentVersion = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString();
|
||||
|
||||
// 创建并显示更新窗口
|
||||
HasNewUpdateWindow updateWindow = new HasNewUpdateWindow(currentVersion, remoteVersion, "", apiReleaseNotes);
|
||||
updateWindow.Owner = Application.Current.MainWindow;
|
||||
bool? dialogResult = updateWindow.ShowDialog();
|
||||
|
||||
// 如果窗口被关闭但没有点击按钮,则不执行任何操作
|
||||
if (dialogResult != true)
|
||||
{
|
||||
LogHelper.WriteLogToFile("ManualUpdate | Update dialog closed without selection");
|
||||
return;
|
||||
}
|
||||
|
||||
// 根据用户选择处理更新
|
||||
switch (updateWindow.Result)
|
||||
{
|
||||
case HasNewUpdateWindow.UpdateResult.UpdateNow:
|
||||
// 立即更新:显示下载进度,下载完成后立即安装
|
||||
LogHelper.WriteLogToFile("ManualUpdate | User chose to update now");
|
||||
|
||||
// 显示下载进度提示
|
||||
MessageBox.Show("开始下载更新,请稍候...", "正在更新", MessageBoxButton.OK, MessageBoxImage.Information);
|
||||
|
||||
// 下载更新文件,使用多线路组下载功能
|
||||
bool isDownloadSuccessful = await DownloadUpdateWithFallback(remoteVersion, lineGroup, Settings.Startup.UpdateChannel);
|
||||
|
||||
if (isDownloadSuccessful)
|
||||
{
|
||||
// 下载成功,提示用户准备安装
|
||||
MessageBoxResult result = MessageBox.Show("更新已下载完成,点击确定后将关闭软件并安装新版本!", "安装更新", MessageBoxButton.OKCancel, MessageBoxImage.Information);
|
||||
|
||||
// 只有当用户点击确定按钮后才关闭软件
|
||||
if (result == MessageBoxResult.OK)
|
||||
{
|
||||
// 设置为用户主动退出,避免被看门狗判定为崩溃
|
||||
App.IsAppExitByUser = true;
|
||||
|
||||
// 准备批处理脚本
|
||||
AutoUpdateHelper.InstallNewVersionApp(remoteVersion, true);
|
||||
|
||||
// 关闭软件,让安装程序接管
|
||||
Application.Current.Shutdown();
|
||||
}
|
||||
else
|
||||
{
|
||||
LogHelper.WriteLogToFile("ManualUpdate | User cancelled update installation");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 下载失败
|
||||
MessageBox.Show("更新下载失败,请检查网络连接后重试。", "下载失败", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
}
|
||||
break;
|
||||
|
||||
case HasNewUpdateWindow.UpdateResult.UpdateLater:
|
||||
// 稍后更新:静默下载,在软件关闭时自动安装
|
||||
LogHelper.WriteLogToFile("ManualUpdate | User chose to update later");
|
||||
|
||||
// 不管设置如何,都进行下载,使用多线路组下载功能
|
||||
isDownloadSuccessful = await DownloadUpdateWithFallback(remoteVersion, lineGroup, Settings.Startup.UpdateChannel);
|
||||
|
||||
if (isDownloadSuccessful)
|
||||
{
|
||||
LogHelper.WriteLogToFile("ManualUpdate | Update downloaded successfully, will install when application closes");
|
||||
|
||||
// 设置标志,在应用程序关闭时安装
|
||||
Settings.Startup.IsAutoUpdate = true;
|
||||
Settings.Startup.IsAutoUpdateWithSilence = true;
|
||||
|
||||
// 启动检查定时器
|
||||
timerCheckAutoUpdateWithSilence.Start();
|
||||
|
||||
// 通知用户
|
||||
MessageBox.Show("更新已下载完成,将在软件关闭时自动安装。", "更新已准备就绪", MessageBoxButton.OK, MessageBoxImage.Information);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogHelper.WriteLogToFile("ManualUpdate | Update download failed", LogHelper.LogType.Error);
|
||||
MessageBox.Show("更新下载失败,请检查网络连接后重试。", "下载失败", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
}
|
||||
break;
|
||||
|
||||
case HasNewUpdateWindow.UpdateResult.SkipVersion:
|
||||
// 跳过该版本:记录到设置中
|
||||
LogHelper.WriteLogToFile($"ManualUpdate | User chose to skip version {remoteVersion}");
|
||||
|
||||
// 记录要跳过的版本号
|
||||
Settings.Startup.SkippedVersion = remoteVersion;
|
||||
|
||||
// 保存设置到文件
|
||||
SaveSettingsToFile();
|
||||
|
||||
// 通知用户
|
||||
MessageBox.Show($"已设置跳过版本 {remoteVersion},在下次发布新版本之前不会再提示更新。",
|
||||
"已跳过此版本",
|
||||
MessageBoxButton.OK,
|
||||
MessageBoxImage.Information);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 没有更新
|
||||
LogHelper.WriteLogToFile("ManualUpdate | No updates available");
|
||||
MessageBox.Show("当前已是最新版本!", "无可用更新", MessageBoxButton.OK, MessageBoxImage.Information);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogHelper.WriteLogToFile($"Error in ManualUpdateButton_Click: {ex.Message}", LogHelper.LogType.Error);
|
||||
MessageBox.Show(
|
||||
$"手动更新过程中发生错误: {ex.Message}",
|
||||
"更新错误",
|
||||
MessageBoxButton.OK,
|
||||
MessageBoxImage.Error);
|
||||
}
|
||||
finally
|
||||
{
|
||||
// 恢复按钮状态
|
||||
ManualUpdateButton.IsEnabled = true;
|
||||
ManualUpdateButton.Content = "手动更新";
|
||||
}
|
||||
}
|
||||
|
||||
private async void FixVersionButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
// 显示确认对话框
|
||||
|
||||
@@ -10,8 +10,10 @@ using System.Windows.Ink;
|
||||
using System.Windows.Interop;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Threading;
|
||||
using File = System.IO.File;
|
||||
using OperatingSystem = OSVersionExtension.OperatingSystem;
|
||||
using WinForms = System.Windows.Forms;
|
||||
|
||||
namespace Ink_Canvas
|
||||
{
|
||||
@@ -28,7 +30,7 @@ namespace Ink_Canvas
|
||||
{
|
||||
string text = File.ReadAllText(App.RootPath + settingsFileName);
|
||||
Settings = JsonConvert.DeserializeObject<Settings>(text);
|
||||
|
||||
|
||||
// 验证设置是否成功加载
|
||||
if (Settings == null)
|
||||
{
|
||||
@@ -42,7 +44,7 @@ namespace Ink_Canvas
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 如果仍然失败,使用默认设置
|
||||
if (Settings == null)
|
||||
{
|
||||
@@ -54,7 +56,7 @@ namespace Ink_Canvas
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogHelper.WriteLogToFile($"配置文件加载失败: {ex.Message}", LogHelper.LogType.Error);
|
||||
|
||||
|
||||
// 尝试从备份恢复
|
||||
LogHelper.WriteLogToFile("尝试从备份恢复配置文件", LogHelper.LogType.Warning);
|
||||
if (AutoBackupManager.TryRestoreFromBackup())
|
||||
@@ -73,7 +75,7 @@ namespace Ink_Canvas
|
||||
BtnResetToSuggestion_Click(null, null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 如果仍然失败,使用默认设置
|
||||
if (Settings == null)
|
||||
{
|
||||
@@ -107,7 +109,7 @@ namespace Ink_Canvas
|
||||
LogHelper.WriteLogToFile("备份恢复失败,使用默认设置", LogHelper.LogType.Warning);
|
||||
BtnResetToSuggestion_Click(null, null);
|
||||
}
|
||||
|
||||
|
||||
// 如果仍然失败,使用默认设置
|
||||
if (Settings == null)
|
||||
{
|
||||
@@ -425,7 +427,7 @@ namespace Ink_Canvas
|
||||
|
||||
// 应用浮动栏按钮可见性设置
|
||||
UpdateFloatingBarButtonsVisibility();
|
||||
|
||||
|
||||
// 更新浮动栏图标
|
||||
UpdateFloatingBarIcons();
|
||||
|
||||
@@ -652,6 +654,7 @@ namespace Ink_Canvas
|
||||
|
||||
// 初始化屏蔽压感开关状态
|
||||
ToggleSwitchDisablePressure.IsOn = Settings.Canvas.DisablePressure;
|
||||
inkCanvas.DefaultDrawingAttributes.IgnorePressure = Settings.Canvas.DisablePressure;
|
||||
|
||||
ComboBoxPenStyle.SelectedIndex = Settings.Canvas.InkStyle;
|
||||
BoardComboBoxPenStyle.SelectedIndex = Settings.Canvas.InkStyle;
|
||||
@@ -803,7 +806,7 @@ namespace Ink_Canvas
|
||||
ToggleSwitchIsEnableAvoidFullScreenHelper.IsOn = Settings.Advanced.IsEnableAvoidFullScreenHelper;
|
||||
ToggleSwitchIsAutoBackupBeforeUpdate.IsOn = Settings.Advanced.IsAutoBackupBeforeUpdate;
|
||||
ToggleSwitchIsAutoBackupEnabled.IsOn = Settings.Advanced.IsAutoBackupEnabled;
|
||||
|
||||
|
||||
// 设置备份间隔下拉框
|
||||
foreach (ComboBoxItem item in ComboBoxAutoBackupInterval.Items)
|
||||
{
|
||||
@@ -820,6 +823,14 @@ namespace Ink_Canvas
|
||||
if (Settings.Advanced.IsEnableAvoidFullScreenHelper)
|
||||
{
|
||||
AvoidFullScreenHelper.StartAvoidFullScreen(this);
|
||||
Dispatcher.BeginInvoke(new Action(() =>
|
||||
{
|
||||
if (isLoaded)
|
||||
{
|
||||
MoveWindow(new WindowInteropHelper(this).Handle, 0, 0,
|
||||
WinForms.Screen.PrimaryScreen.Bounds.Width, WinForms.Screen.PrimaryScreen.Bounds.Height, true);
|
||||
}
|
||||
}), DispatcherPriority.ApplicationIdle);
|
||||
}
|
||||
if (Settings.Advanced.IsEnableEdgeGestureUtil)
|
||||
{
|
||||
@@ -865,6 +876,7 @@ namespace Ink_Canvas
|
||||
RandWindowOnceCloseLatencySlider.Value = Settings.RandSettings.RandWindowOnceCloseLatency;
|
||||
RandWindowOnceMaxStudentsSlider.Value = Settings.RandSettings.RandWindowOnceMaxStudents;
|
||||
ToggleSwitchShowRandomAndSingleDraw.IsOn = Settings.RandSettings.ShowRandomAndSingleDraw;
|
||||
ToggleSwitchEnableQuickDraw.IsOn = Settings.RandSettings.EnableQuickDraw;
|
||||
ToggleSwitchExternalCaller.IsOn = Settings.RandSettings.DirectCallCiRand;
|
||||
ComboBoxExternalCallerType.SelectedIndex = Settings.RandSettings.ExternalCallerType;
|
||||
RandomDrawPanel.Visibility = Settings.RandSettings.ShowRandomAndSingleDraw ? Visibility.Visible : Visibility.Collapsed;
|
||||
@@ -872,8 +884,28 @@ namespace Ink_Canvas
|
||||
|
||||
// 计时器设置
|
||||
ToggleSwitchUseLegacyTimerUI.IsOn = Settings.RandSettings.UseLegacyTimerUI;
|
||||
ToggleSwitchUseNewStyleUI.IsOn = Settings.RandSettings.UseNewStyleUI;
|
||||
ToggleSwitchEnableOvertimeCountUp.IsOn = Settings.RandSettings.EnableOvertimeCountUp;
|
||||
|
||||
// 新点名UI设置
|
||||
ToggleSwitchUseNewRollCallUI.IsOn = Settings.RandSettings.UseNewRollCallUI;
|
||||
ToggleSwitchEnableMLAvoidance.IsOn = Settings.RandSettings.EnableMLAvoidance;
|
||||
MLAvoidanceHistorySlider.Value = Settings.RandSettings.MLAvoidanceHistoryCount;
|
||||
MLAvoidanceWeightSlider.Value = Settings.RandSettings.MLAvoidanceWeight;
|
||||
|
||||
bool canEnableRedText = Settings.RandSettings.EnableOvertimeCountUp && Settings.RandSettings.EnableOvertimeRedText;
|
||||
ToggleSwitchEnableOvertimeRedText.IsOn = canEnableRedText;
|
||||
if (!canEnableRedText)
|
||||
{
|
||||
Settings.RandSettings.EnableOvertimeRedText = false;
|
||||
}
|
||||
|
||||
TimerVolumeSlider.Value = Settings.RandSettings.TimerVolume;
|
||||
|
||||
// 渐进提醒设置
|
||||
ToggleSwitchEnableProgressiveReminder.IsOn = Settings.RandSettings.EnableProgressiveReminder;
|
||||
ProgressiveReminderVolumeSlider.Value = Settings.RandSettings.ProgressiveReminderVolume;
|
||||
|
||||
// 加载自定义点名背景
|
||||
UpdatePickNameBackgroundsInComboBox();
|
||||
|
||||
@@ -890,17 +922,32 @@ namespace Ink_Canvas
|
||||
ToggleSwitchDisplayRandWindowNamesInputBtn.IsOn = Settings.RandSettings.DisplayRandWindowNamesInputBtn;
|
||||
RandWindowOnceCloseLatencySlider.Value = Settings.RandSettings.RandWindowOnceCloseLatency;
|
||||
RandWindowOnceMaxStudentsSlider.Value = Settings.RandSettings.RandWindowOnceMaxStudents;
|
||||
ToggleSwitchEnableQuickDraw.IsOn = Settings.RandSettings.EnableQuickDraw;
|
||||
ToggleSwitchExternalCaller.IsOn = Settings.RandSettings.DirectCallCiRand;
|
||||
ComboBoxExternalCallerType.SelectedIndex = Settings.RandSettings.ExternalCallerType;
|
||||
ToggleSwitchUseLegacyTimerUI.IsOn = Settings.RandSettings.UseLegacyTimerUI;
|
||||
ToggleSwitchUseNewStyleUI.IsOn = Settings.RandSettings.UseNewStyleUI;
|
||||
ToggleSwitchEnableOvertimeCountUp.IsOn = Settings.RandSettings.EnableOvertimeCountUp;
|
||||
|
||||
bool canEnableRedText = Settings.RandSettings.EnableOvertimeCountUp && Settings.RandSettings.EnableOvertimeRedText;
|
||||
ToggleSwitchEnableOvertimeRedText.IsOn = canEnableRedText;
|
||||
if (!canEnableRedText)
|
||||
{
|
||||
Settings.RandSettings.EnableOvertimeRedText = false;
|
||||
}
|
||||
|
||||
TimerVolumeSlider.Value = Settings.RandSettings.TimerVolume;
|
||||
|
||||
// 渐进提醒设置
|
||||
ToggleSwitchEnableProgressiveReminder.IsOn = Settings.RandSettings.EnableProgressiveReminder;
|
||||
ProgressiveReminderVolumeSlider.Value = Settings.RandSettings.ProgressiveReminderVolume;
|
||||
}
|
||||
|
||||
// ModeSettings
|
||||
if (Settings.ModeSettings != null)
|
||||
{
|
||||
ToggleSwitchMode.IsOn = Settings.ModeSettings.IsPPTOnlyMode;
|
||||
|
||||
|
||||
// 根据加载的配置状态执行相应的窗口显示/隐藏逻辑
|
||||
if (isStartup && Settings.ModeSettings.IsPPTOnlyMode)
|
||||
{
|
||||
@@ -1006,6 +1053,23 @@ namespace Ink_Canvas
|
||||
|
||||
ToggleSwitchSaveFullPageStrokes.IsOn = Settings.Automation.IsSaveFullPageStrokes;
|
||||
|
||||
// 加载定时保存墨迹设置
|
||||
ToggleSwitchEnableAutoSaveStrokes.IsOn = Settings.Automation.IsEnableAutoSaveStrokes;
|
||||
// 初始化保存间隔下拉框
|
||||
if (ComboBoxAutoSaveStrokesInterval != null)
|
||||
{
|
||||
int intervalMinutes = Settings.Automation.AutoSaveStrokesIntervalMinutes;
|
||||
if (intervalMinutes < 1) intervalMinutes = 5; // 默认5分钟
|
||||
foreach (System.Windows.Controls.ComboBoxItem item in ComboBoxAutoSaveStrokesInterval.Items)
|
||||
{
|
||||
if (item.Tag != null && int.TryParse(item.Tag.ToString(), out int tagValue) && tagValue == intervalMinutes)
|
||||
{
|
||||
ComboBoxAutoSaveStrokesInterval.SelectedItem = item;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SideControlMinimumAutomationSlider.Value = Settings.Automation.MinimumAutomationStrokeNumber;
|
||||
|
||||
AutoSavedStrokesLocation.Text = Settings.Automation.AutoSavedStrokesLocation;
|
||||
@@ -1015,7 +1079,7 @@ namespace Ink_Canvas
|
||||
|
||||
// 加载退出收纳模式自动切换至批注模式设置
|
||||
ToggleSwitchAutoEnterAnnotationModeWhenExitFoldMode.IsOn = Settings.Automation.IsAutoEnterAnnotationModeWhenExitFoldMode;
|
||||
|
||||
|
||||
// 加载退出白板时自动收纳设置
|
||||
ToggleSwitchAutoFoldWhenExitWhiteboard.IsOn = Settings.Automation.IsAutoFoldWhenExitWhiteboard;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Ink_Canvas.Helpers;
|
||||
using Ink_Canvas.Helpers;
|
||||
using iNKORE.UI.WPF.Modern.Controls;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -343,7 +343,7 @@ namespace Ink_Canvas
|
||||
await CheckIsDrawingShapesInMultiTouchMode();
|
||||
EnterShapeDrawingMode(3);
|
||||
CancelSingleFingerDragMode();
|
||||
isLongPressSelected = false;
|
||||
isLongPressSelected = false;
|
||||
lastMouseDownSender = null;
|
||||
DrawShapePromptToPen();
|
||||
}
|
||||
@@ -496,7 +496,7 @@ namespace Ink_Canvas
|
||||
if (!isTouchDown) return;
|
||||
|
||||
if (isWaitUntilNextTouchDown && dec.Count > 1) return;
|
||||
|
||||
|
||||
// 对于多笔图形绘制,允许第二笔绘制,即使dec.Count > 1
|
||||
if (dec.Count > 1 && !((drawingShapeMode == 24 || drawingShapeMode == 25) && drawMultiStepShapeCurrentStep == 1))
|
||||
{
|
||||
@@ -512,7 +512,7 @@ namespace Ink_Canvas
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// 第二笔绘制双曲线时,只删除第二笔的临时笔画,保留第一笔的辅助线
|
||||
if ((drawingShapeMode == 24 || drawingShapeMode == 25) && drawMultiStepShapeCurrentStep == 1)
|
||||
{
|
||||
@@ -584,19 +584,19 @@ namespace Ink_Canvas
|
||||
{
|
||||
DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone()
|
||||
};
|
||||
|
||||
|
||||
UpdateTempStrokeSafely(stroke);
|
||||
break;
|
||||
case 8:
|
||||
_currentCommitType = CommitReason.ShapeDrawing;
|
||||
strokes.Add(GenerateDashedLineStrokeCollection(iniP, endP));
|
||||
|
||||
|
||||
UpdateTempStrokeCollectionSafely(strokes);
|
||||
break;
|
||||
case 18:
|
||||
_currentCommitType = CommitReason.ShapeDrawing;
|
||||
strokes.Add(GenerateDotLineStrokeCollection(iniP, endP));
|
||||
|
||||
|
||||
UpdateTempStrokeCollectionSafely(strokes);
|
||||
break;
|
||||
case 2:
|
||||
@@ -618,7 +618,7 @@ namespace Ink_Canvas
|
||||
{
|
||||
DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone()
|
||||
};
|
||||
|
||||
|
||||
// 优化:使用更安全的临时笔画更新方式,减少闪烁
|
||||
UpdateTempStrokeSafely(stroke);
|
||||
break;
|
||||
@@ -1503,12 +1503,12 @@ namespace Ink_Canvas
|
||||
{
|
||||
// 先添加新笔画,再删除旧笔画,减少视觉闪烁
|
||||
inkCanvas.Strokes.Add(newStroke);
|
||||
|
||||
|
||||
if (lastTempStroke != null && inkCanvas.Strokes.Contains(lastTempStroke))
|
||||
{
|
||||
inkCanvas.Strokes.Remove(lastTempStroke);
|
||||
}
|
||||
|
||||
|
||||
lastTempStroke = newStroke;
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -1553,7 +1553,7 @@ namespace Ink_Canvas
|
||||
{
|
||||
// 先添加新笔画集合,再删除旧笔画集合,减少视觉闪烁
|
||||
inkCanvas.Strokes.Add(newStrokeCollection);
|
||||
|
||||
|
||||
if (lastTempStrokeCollection != null && lastTempStrokeCollection.Count > 0)
|
||||
{
|
||||
foreach (var stroke in lastTempStrokeCollection)
|
||||
@@ -1564,7 +1564,7 @@ namespace Ink_Canvas
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
lastTempStrokeCollection = newStrokeCollection;
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -2143,4 +2143,4 @@ namespace Ink_Canvas
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -744,13 +744,13 @@ namespace Ink_Canvas
|
||||
// 应用高级贝塞尔曲线平滑(仅在未进行直线拉直时)
|
||||
Debug.WriteLine($"墨迹平滑检查: UseAdvancedBezierSmoothing={Settings.Canvas.UseAdvancedBezierSmoothing}, wasStraightened={wasStraightened}");
|
||||
Debug.WriteLine($"异步平滑设置: UseAsyncInkSmoothing={Settings.Canvas.UseAsyncInkSmoothing}, _inkSmoothingManager={_inkSmoothingManager != null}");
|
||||
|
||||
|
||||
if (Settings.Canvas.UseAdvancedBezierSmoothing && !wasStraightened)
|
||||
{
|
||||
try
|
||||
{
|
||||
Debug.WriteLine($"开始墨迹平滑处理: 原始点数={e.Stroke.StylusPoints.Count}, 直线拉直={wasStraightened}");
|
||||
|
||||
|
||||
// 检查原始笔画是否仍然存在于画布中
|
||||
if (inkCanvas.Strokes.Contains(e.Stroke))
|
||||
{
|
||||
@@ -807,7 +807,7 @@ namespace Ink_Canvas
|
||||
Debug.WriteLine($"异步平滑完成: 原始点数={original.StylusPoints.Count}, 平滑后点数={smoothed.StylusPoints.Count}");
|
||||
Debug.WriteLine($"墨迹比较: smoothed != original = {smoothed != original}");
|
||||
Debug.WriteLine($"画布包含原始墨迹: {inkCanvas.Strokes.Contains(original)}");
|
||||
|
||||
|
||||
// 在UI线程上执行笔画替换
|
||||
if (inkCanvas.Strokes.Contains(original) && smoothed != original)
|
||||
{
|
||||
@@ -1424,7 +1424,7 @@ namespace Ink_Canvas
|
||||
// 修复灵敏度逻辑:灵敏度越大,容许的偏差越大,更容易将线条识别为直线
|
||||
// 将灵敏度转换为阈值:灵敏度0.05-1.0映射到阈值0.01-0.2
|
||||
double threshold = Math.Max(0.01, sensitivity * 0.2); // 确保最小阈值为0.01
|
||||
|
||||
|
||||
if ((maxDeviation / lineLength) > threshold)
|
||||
{
|
||||
Debug.WriteLine($"拒绝拉直:最大偏差过大 {maxDeviation / lineLength:F3} > {threshold:F3}");
|
||||
|
||||
@@ -12,6 +12,7 @@ using System.Threading.Tasks;
|
||||
using System.Timers;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Threading;
|
||||
|
||||
namespace Ink_Canvas
|
||||
{
|
||||
@@ -61,8 +62,10 @@ namespace Ink_Canvas
|
||||
private Timer timerCheckAutoFold = new Timer();
|
||||
private string AvailableLatestVersion;
|
||||
private Timer timerCheckAutoUpdateWithSilence = new Timer();
|
||||
private Timer timerCheckAutoUpdateRetry = new Timer();
|
||||
private bool isHidingSubPanelsWhenInking; // 避免书写时触发二次关闭二级菜单导致动画不连续
|
||||
|
||||
private int updateCheckRetryCount = 0;
|
||||
private const int MAX_UPDATE_CHECK_RETRIES = 6;
|
||||
private Timer timerDisplayTime = new Timer();
|
||||
private Timer timerDisplayDate = new Timer();
|
||||
private Timer timerNtpSync = new Timer();
|
||||
@@ -70,8 +73,8 @@ namespace Ink_Canvas
|
||||
private TimeViewModel nowTimeVM = new TimeViewModel();
|
||||
private DateTime cachedNetworkTime = DateTime.Now;
|
||||
private DateTime lastNtpSyncTime = DateTime.MinValue;
|
||||
private string lastDisplayedTime = "";
|
||||
private bool useNetworkTime = false;
|
||||
private string lastDisplayedTime = "";
|
||||
private bool useNetworkTime = false;
|
||||
private TimeSpan networkTimeOffset = TimeSpan.Zero;
|
||||
private DateTime lastLocalTime = DateTime.Now; // 记录上次的本地时间,用于检测时间跳跃
|
||||
private bool isNtpSyncing = false; // 防止重复NTP同步的标志
|
||||
@@ -87,7 +90,7 @@ namespace Ink_Canvas
|
||||
var ipEndPoint = new IPEndPoint(addresses[0], 123);
|
||||
using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp))
|
||||
{
|
||||
socket.ReceiveTimeout = 5000;
|
||||
socket.ReceiveTimeout = 5000;
|
||||
socket.Connect(ipEndPoint);
|
||||
await Task.Factory.FromAsync(socket.BeginSend(ntpData, 0, ntpData.Length, SocketFlags.None, null, socket), socket.EndSend);
|
||||
await Task.Factory.FromAsync(socket.BeginReceive(ntpData, 0, ntpData.Length, SocketFlags.None, null, socket), socket.EndReceive);
|
||||
@@ -117,6 +120,8 @@ namespace Ink_Canvas
|
||||
timerCheckAutoFold.Interval = 500;
|
||||
timerCheckAutoUpdateWithSilence.Elapsed += timerCheckAutoUpdateWithSilence_Elapsed;
|
||||
timerCheckAutoUpdateWithSilence.Interval = 1000 * 60 * 10;
|
||||
timerCheckAutoUpdateRetry.Elapsed += timerCheckAutoUpdateRetry_Elapsed;
|
||||
timerCheckAutoUpdateRetry.Interval = 1000 * 60 * 10;
|
||||
WaterMarkTime.DataContext = nowTimeVM;
|
||||
WaterMarkDate.DataContext = nowTimeVM;
|
||||
timerDisplayTime.Elapsed += TimerDisplayTime_Elapsed;
|
||||
@@ -131,7 +136,7 @@ namespace Ink_Canvas
|
||||
timerKillProcess.Start();
|
||||
nowTimeVM.nowDate = DateTime.Now.ToString("yyyy'年'MM'月'dd'日' dddd");
|
||||
nowTimeVM.nowTime = DateTime.Now.ToString("tt hh'时'mm'分'ss'秒'");
|
||||
|
||||
|
||||
// 程序启动时立即进行一次NTP同步
|
||||
Task.Run(async () =>
|
||||
{
|
||||
@@ -144,6 +149,55 @@ namespace Ink_Canvas
|
||||
LogHelper.WriteLogToFile($"程序启动时NTP同步失败: {ex.Message}", LogHelper.LogType.Error);
|
||||
}
|
||||
});
|
||||
|
||||
// 初始化定时保存墨迹定时器
|
||||
InitAutoSaveStrokesTimer();
|
||||
}
|
||||
|
||||
// 初始化定时保存墨迹定时器
|
||||
private void InitAutoSaveStrokesTimer()
|
||||
{
|
||||
if (autoSaveStrokesTimer == null)
|
||||
{
|
||||
autoSaveStrokesTimer = new DispatcherTimer();
|
||||
autoSaveStrokesTimer.Tick += AutoSaveStrokesTimer_Tick;
|
||||
}
|
||||
|
||||
// 根据设置更新定时器间隔和启动状态
|
||||
UpdateAutoSaveStrokesTimer();
|
||||
}
|
||||
|
||||
// 更新定时保存墨迹定时器状态
|
||||
private void UpdateAutoSaveStrokesTimer()
|
||||
{
|
||||
if (autoSaveStrokesTimer == null) return;
|
||||
|
||||
autoSaveStrokesTimer.Stop();
|
||||
|
||||
if (Settings.Automation.IsEnableAutoSaveStrokes)
|
||||
{
|
||||
int intervalMinutes = Settings.Automation.AutoSaveStrokesIntervalMinutes;
|
||||
if (intervalMinutes < 1) intervalMinutes = 1; // 最小间隔1分钟
|
||||
autoSaveStrokesTimer.Interval = TimeSpan.FromMinutes(intervalMinutes);
|
||||
autoSaveStrokesTimer.Start();
|
||||
}
|
||||
}
|
||||
|
||||
// 定时保存墨迹定时器事件处理
|
||||
private void AutoSaveStrokesTimer_Tick(object sender, EventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 只有在画布可见且有墨迹时才保存
|
||||
if (inkCanvas.Visibility == Visibility.Visible && inkCanvas.Strokes.Count > 0)
|
||||
{
|
||||
// 静默保存
|
||||
SaveInkCanvasStrokes(false, false);
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
// NTP同步定时器事件处理
|
||||
@@ -151,17 +205,17 @@ namespace Ink_Canvas
|
||||
{
|
||||
// 防止重复同步
|
||||
if (isNtpSyncing) return;
|
||||
|
||||
|
||||
isNtpSyncing = true;
|
||||
try
|
||||
{
|
||||
|
||||
|
||||
// 添加超时机制,最多等待10秒
|
||||
var timeoutTask = Task.Delay(10000);
|
||||
var ntpTask = GetNetworkTimeAsync();
|
||||
|
||||
|
||||
var completedTask = await Task.WhenAny(ntpTask, timeoutTask);
|
||||
|
||||
|
||||
if (completedTask == timeoutTask)
|
||||
{
|
||||
cachedNetworkTime = DateTime.Now;
|
||||
@@ -170,20 +224,20 @@ namespace Ink_Canvas
|
||||
networkTimeOffset = TimeSpan.Zero;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
DateTime networkTime = await ntpTask;
|
||||
DateTime localTime = DateTime.Now;
|
||||
|
||||
|
||||
cachedNetworkTime = networkTime;
|
||||
lastNtpSyncTime = localTime;
|
||||
|
||||
|
||||
// 计算网络时间与本地时间的偏移量
|
||||
networkTimeOffset = networkTime - localTime;
|
||||
|
||||
|
||||
// 如果时间差超过3分钟,则使用网络时间
|
||||
useNetworkTime = Math.Abs(networkTimeOffset.TotalMinutes) > 3.0;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// NTP同步失败时,保持使用本地时间
|
||||
@@ -191,7 +245,7 @@ namespace Ink_Canvas
|
||||
lastNtpSyncTime = DateTime.Now;
|
||||
useNetworkTime = false;
|
||||
networkTimeOffset = TimeSpan.Zero;
|
||||
|
||||
|
||||
LogHelper.WriteLogToFile($"NTP同步失败: {ex.Message}", LogHelper.LogType.Warning);
|
||||
}
|
||||
finally
|
||||
@@ -209,7 +263,7 @@ namespace Ink_Canvas
|
||||
// 检测系统时间是否发生重大跳跃(超过2分钟)
|
||||
TimeSpan timeJump = localTime - lastLocalTime;
|
||||
double timeJumpMinutes = Math.Abs(timeJump.TotalMinutes);
|
||||
|
||||
|
||||
if (timeJumpMinutes > 3 && !isNtpSyncing)
|
||||
{
|
||||
// 系统时间发生重大变化(超过3分钟),立即触发NTP同步
|
||||
@@ -237,12 +291,12 @@ namespace Ink_Canvas
|
||||
// 格式化时间字符串
|
||||
string timeString = displayTime.ToString("tt hh'时'mm'分'ss'秒'");
|
||||
|
||||
|
||||
|
||||
// 只有当时间字符串发生变化时才更新UI,避免不必要的UI刷新
|
||||
if (timeString != lastDisplayedTime)
|
||||
{
|
||||
lastDisplayedTime = timeString;
|
||||
|
||||
|
||||
// 使用BeginInvoke异步更新UI,避免阻塞
|
||||
Dispatcher.BeginInvoke(new Action(() =>
|
||||
{
|
||||
@@ -477,7 +531,7 @@ namespace Ink_Canvas
|
||||
{ // EasiNote5
|
||||
// 检查是否是桌面批注窗口
|
||||
bool isAnnotationWindow = windowTitle.Length == 0 && ForegroundWindowInfo.WindowRect().Height < 500;
|
||||
|
||||
|
||||
// 如果启用了忽略桌面批注窗口功能,且当前是批注窗口
|
||||
if (Settings.Automation.IsAutoFoldInEasiNoteIgnoreDesktopAnno && isAnnotationWindow)
|
||||
{
|
||||
@@ -830,5 +884,92 @@ namespace Ink_Canvas
|
||||
timerCheckAutoUpdateWithSilence.Start();
|
||||
}
|
||||
}
|
||||
|
||||
// 检查更新失败重试定时器事件处理
|
||||
private async void timerCheckAutoUpdateRetry_Elapsed(object sender, ElapsedEventArgs e)
|
||||
{
|
||||
// 停止定时器,避免重复触发
|
||||
timerCheckAutoUpdateRetry.Stop();
|
||||
|
||||
try
|
||||
{
|
||||
// 检查是否启用了自动更新
|
||||
if (!Settings.Startup.IsAutoUpdate)
|
||||
{
|
||||
LogHelper.WriteLogToFile("AutoUpdate | Auto update is disabled, stopping retry timer");
|
||||
return;
|
||||
}
|
||||
|
||||
// 增加重试计数
|
||||
updateCheckRetryCount++;
|
||||
LogHelper.WriteLogToFile($"AutoUpdate | Retry check attempt {updateCheckRetryCount}/{MAX_UPDATE_CHECK_RETRIES}");
|
||||
|
||||
// 检查是否超过最大重试次数
|
||||
if (updateCheckRetryCount > MAX_UPDATE_CHECK_RETRIES)
|
||||
{
|
||||
LogHelper.WriteLogToFile("AutoUpdate | Maximum retry attempts reached, stopping retry timer", LogHelper.LogType.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
// 执行更新检查
|
||||
LogHelper.WriteLogToFile("AutoUpdate | Retrying update check after failure");
|
||||
|
||||
// 清除之前的更新状态
|
||||
AvailableLatestVersion = null;
|
||||
AvailableLatestLineGroup = null;
|
||||
|
||||
// 使用当前选择的更新通道检查更新
|
||||
var (remoteVersion, lineGroup, apiReleaseNotes) = await AutoUpdateHelper.CheckForUpdates(Settings.Startup.UpdateChannel);
|
||||
AvailableLatestVersion = remoteVersion;
|
||||
AvailableLatestLineGroup = lineGroup;
|
||||
|
||||
if (AvailableLatestVersion != null)
|
||||
{
|
||||
// 检查更新成功,重置重试计数
|
||||
updateCheckRetryCount = 0;
|
||||
LogHelper.WriteLogToFile($"AutoUpdate | Retry successful, found new version: {AvailableLatestVersion}");
|
||||
|
||||
// 停止重试定时器,因为已经找到了更新
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 检查更新仍然失败,继续重试
|
||||
LogHelper.WriteLogToFile($"AutoUpdate | Retry {updateCheckRetryCount} failed, will retry in 10 minutes");
|
||||
|
||||
// 重新启动定时器,10分钟后再次尝试
|
||||
timerCheckAutoUpdateRetry.Start();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogHelper.WriteLogToFile($"AutoUpdate | Error in retry check: {ex.Message}", LogHelper.LogType.Error);
|
||||
|
||||
// 出错时也重新启动定时器,稍后再检查
|
||||
if (updateCheckRetryCount <= MAX_UPDATE_CHECK_RETRIES)
|
||||
{
|
||||
timerCheckAutoUpdateRetry.Start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 重置更新检查重试状态
|
||||
public void ResetUpdateCheckRetry()
|
||||
{
|
||||
try
|
||||
{
|
||||
// 停止重试定时器
|
||||
timerCheckAutoUpdateRetry.Stop();
|
||||
|
||||
// 重置重试计数
|
||||
updateCheckRetryCount = 0;
|
||||
|
||||
LogHelper.WriteLogToFile("AutoUpdate | Update check retry state reset");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogHelper.WriteLogToFile($"AutoUpdate | Error resetting retry state: {ex.Message}", LogHelper.LogType.Error);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,9 +23,9 @@ namespace Ink_Canvas
|
||||
private Point centerPoint = new Point(0, 0);
|
||||
private InkCanvasEditingMode lastInkCanvasEditingMode = InkCanvasEditingMode.Ink;
|
||||
private DateTime lastTouchDownTime = DateTime.MinValue;
|
||||
private const double MULTI_TOUCH_DELAY_MS = 100;
|
||||
private const double MULTI_TOUCH_DELAY_MS = 100;
|
||||
private bool isMultiTouchTimerActive = false;
|
||||
|
||||
|
||||
/// </summary>
|
||||
/// 保存画布上的非笔画元素(如图片、媒体元素等)
|
||||
/// </summary>
|
||||
@@ -64,13 +64,13 @@ namespace Ink_Canvas
|
||||
if (originalElement is Image originalImage)
|
||||
{
|
||||
var clonedImage = new Image();
|
||||
|
||||
|
||||
// 复制图片源
|
||||
if (originalImage.Source is BitmapSource bitmapSource)
|
||||
{
|
||||
clonedImage.Source = bitmapSource;
|
||||
}
|
||||
|
||||
|
||||
// 复制属性
|
||||
clonedImage.Width = originalImage.Width;
|
||||
clonedImage.Height = originalImage.Height;
|
||||
@@ -81,23 +81,23 @@ namespace Ink_Canvas
|
||||
clonedImage.Focusable = originalImage.Focusable;
|
||||
clonedImage.Cursor = originalImage.Cursor;
|
||||
clonedImage.IsManipulationEnabled = originalImage.IsManipulationEnabled;
|
||||
|
||||
|
||||
// 复制位置
|
||||
InkCanvas.SetLeft(clonedImage, InkCanvas.GetLeft(originalImage));
|
||||
InkCanvas.SetTop(clonedImage, InkCanvas.GetTop(originalImage));
|
||||
|
||||
|
||||
// 复制变换
|
||||
if (originalImage.RenderTransform != null)
|
||||
{
|
||||
clonedImage.RenderTransform = originalImage.RenderTransform.Clone();
|
||||
}
|
||||
|
||||
|
||||
return clonedImage;
|
||||
}
|
||||
else if (originalElement is MediaElement originalMedia)
|
||||
{
|
||||
var clonedMedia = new MediaElement();
|
||||
|
||||
|
||||
// 复制媒体属性
|
||||
clonedMedia.Source = originalMedia.Source;
|
||||
clonedMedia.Width = originalMedia.Width;
|
||||
@@ -105,23 +105,23 @@ namespace Ink_Canvas
|
||||
clonedMedia.Name = originalMedia.Name;
|
||||
clonedMedia.IsHitTestVisible = originalMedia.IsHitTestVisible;
|
||||
clonedMedia.Focusable = originalMedia.Focusable;
|
||||
|
||||
|
||||
// 复制位置
|
||||
InkCanvas.SetLeft(clonedMedia, InkCanvas.GetLeft(originalMedia));
|
||||
InkCanvas.SetTop(clonedMedia, InkCanvas.GetTop(originalMedia));
|
||||
|
||||
|
||||
// 复制变换
|
||||
if (originalMedia.RenderTransform != null)
|
||||
{
|
||||
clonedMedia.RenderTransform = originalMedia.RenderTransform.Clone();
|
||||
}
|
||||
|
||||
|
||||
return clonedMedia;
|
||||
}
|
||||
else if (originalElement is Border originalBorder)
|
||||
{
|
||||
var clonedBorder = new Border();
|
||||
|
||||
|
||||
// 复制边框属性
|
||||
clonedBorder.Width = originalBorder.Width;
|
||||
clonedBorder.Height = originalBorder.Height;
|
||||
@@ -132,17 +132,17 @@ namespace Ink_Canvas
|
||||
clonedBorder.BorderBrush = originalBorder.BorderBrush;
|
||||
clonedBorder.BorderThickness = originalBorder.BorderThickness;
|
||||
clonedBorder.CornerRadius = originalBorder.CornerRadius;
|
||||
|
||||
|
||||
// 复制位置
|
||||
InkCanvas.SetLeft(clonedBorder, InkCanvas.GetLeft(originalBorder));
|
||||
InkCanvas.SetTop(clonedBorder, InkCanvas.GetTop(originalBorder));
|
||||
|
||||
|
||||
// 复制变换
|
||||
if (originalBorder.RenderTransform != null)
|
||||
{
|
||||
clonedBorder.RenderTransform = originalBorder.RenderTransform.Clone();
|
||||
}
|
||||
|
||||
|
||||
return clonedBorder;
|
||||
}
|
||||
}
|
||||
@@ -150,7 +150,7 @@ namespace Ink_Canvas
|
||||
{
|
||||
LogHelper.WriteLogToFile($"克隆UI元素失败: {ex.Message}", LogHelper.LogType.Error);
|
||||
}
|
||||
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -246,20 +246,19 @@ namespace Ink_Canvas
|
||||
if (drawingShapeMode != 0)
|
||||
{
|
||||
inkCanvas.EditingMode = InkCanvasEditingMode.None;
|
||||
|
||||
|
||||
isTouchDown = true;
|
||||
ViewboxFloatingBar.IsHitTestVisible = false;
|
||||
BlackboardUIGridForInkReplay.IsHitTestVisible = false;
|
||||
|
||||
|
||||
// 设置起始点
|
||||
if (NeedUpdateIniP()) iniP = e.GetTouchPoint(inkCanvas).Position;
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// 只保留普通橡皮逻辑
|
||||
TouchDownPointsList[e.TouchDevice.Id] = InkCanvasEditingMode.None;
|
||||
inkCanvas.EraserShape = new EllipseStylusShape(50, 50);
|
||||
if (inkCanvas.EditingMode != InkCanvasEditingMode.EraseByPoint
|
||||
&& inkCanvas.EditingMode != InkCanvasEditingMode.EraseByStroke)
|
||||
{
|
||||
@@ -292,14 +291,14 @@ namespace Ink_Canvas
|
||||
if (drawingShapeMode != 0)
|
||||
{
|
||||
inkCanvas.EditingMode = InkCanvasEditingMode.None;
|
||||
|
||||
|
||||
isTouchDown = true;
|
||||
ViewboxFloatingBar.IsHitTestVisible = false;
|
||||
BlackboardUIGridForInkReplay.IsHitTestVisible = false;
|
||||
|
||||
|
||||
// 设置起始点
|
||||
if (NeedUpdateIniP()) iniP = e.GetPosition(inkCanvas);
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
if (inkCanvas.EditingMode != InkCanvasEditingMode.EraseByStroke)
|
||||
@@ -354,7 +353,7 @@ namespace Ink_Canvas
|
||||
isTouchDown = false;
|
||||
ViewboxFloatingBar.IsHitTestVisible = true;
|
||||
BlackboardUIGridForInkReplay.IsHitTestVisible = true;
|
||||
|
||||
|
||||
// 对于双曲线等需要多步绘制的图形,手写笔抬起时应该进入下一步
|
||||
if (drawingShapeMode == 24 || drawingShapeMode == 25)
|
||||
{
|
||||
@@ -384,7 +383,7 @@ namespace Ink_Canvas
|
||||
};
|
||||
inkCanvas_MouseUp(inkCanvas, mouseArgs);
|
||||
}
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -393,7 +392,7 @@ namespace Ink_Canvas
|
||||
var stroke = GetStrokeVisual(e.StylusDevice.Id).Stroke;
|
||||
|
||||
inkCanvas.Strokes.Add(stroke);
|
||||
await Task.Delay(5);
|
||||
await Task.Delay(5);
|
||||
inkCanvas.Children.Remove(GetVisualCanvas(e.StylusDevice.Id));
|
||||
|
||||
inkCanvas_StrokeCollected(inkCanvas,
|
||||
@@ -538,15 +537,15 @@ namespace Ink_Canvas
|
||||
if (drawingShapeMode != 0)
|
||||
{
|
||||
inkCanvas.EditingMode = InkCanvasEditingMode.None;
|
||||
|
||||
|
||||
// 设置触摸状态,类似鼠标事件处理
|
||||
isTouchDown = true;
|
||||
ViewboxFloatingBar.IsHitTestVisible = false;
|
||||
BlackboardUIGridForInkReplay.IsHitTestVisible = false;
|
||||
|
||||
|
||||
// 设置起始点
|
||||
if (NeedUpdateIniP()) iniP = e.GetTouchPoint(inkCanvas).Position;
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
if (inkCanvas.EditingMode == InkCanvasEditingMode.Ink)
|
||||
@@ -604,7 +603,7 @@ namespace Ink_Canvas
|
||||
inkCanvas.CaptureTouch(e.TouchDevice);
|
||||
ViewboxFloatingBar.IsHitTestVisible = false;
|
||||
BlackboardUIGridForInkReplay.IsHitTestVisible = false;
|
||||
|
||||
|
||||
isTouchDown = true;
|
||||
|
||||
if (dec.Count == 0)
|
||||
@@ -646,7 +645,7 @@ namespace Ink_Canvas
|
||||
double boundWidth = GetTouchBoundWidth(e);
|
||||
|
||||
|
||||
if ((Settings.Advanced.TouchMultiplier != 0 || !Settings.Advanced.IsSpecialScreen)
|
||||
if ((Settings.Advanced.TouchMultiplier != 0 || !Settings.Advanced.IsSpecialScreen)
|
||||
&& (boundWidth > BoundsWidth))
|
||||
{
|
||||
// 根据敏感度调整阈值倍数
|
||||
@@ -665,10 +664,10 @@ namespace Ink_Canvas
|
||||
break;
|
||||
}
|
||||
|
||||
double EraserThresholdValue = Settings.Startup.IsEnableNibMode ?
|
||||
Settings.Advanced.NibModeBoundsWidthThresholdValue :
|
||||
double EraserThresholdValue = Settings.Startup.IsEnableNibMode ?
|
||||
Settings.Advanced.NibModeBoundsWidthThresholdValue :
|
||||
Settings.Advanced.FingerModeBoundsWidthThresholdValue;
|
||||
|
||||
|
||||
if (boundWidth > BoundsWidth * EraserThresholdValue * thresholdMultiplier)
|
||||
{
|
||||
// 记录当前编辑模式和高光状态
|
||||
@@ -676,17 +675,15 @@ namespace Ink_Canvas
|
||||
palmEraserLastIsHighlighter = drawingAttributes.IsHighlighter;
|
||||
|
||||
// 动态调整橡皮大小
|
||||
boundWidth *= (Settings.Startup.IsEnableNibMode ?
|
||||
Settings.Advanced.NibModeBoundsWidthEraserSize :
|
||||
boundWidth *= (Settings.Startup.IsEnableNibMode ?
|
||||
Settings.Advanced.NibModeBoundsWidthEraserSize :
|
||||
Settings.Advanced.FingerModeBoundsWidthEraserSize);
|
||||
|
||||
if (Settings.Advanced.IsSpecialScreen)
|
||||
|
||||
if (Settings.Advanced.IsSpecialScreen)
|
||||
boundWidth *= Settings.Advanced.TouchMultiplier;
|
||||
|
||||
inkCanvas.EraserShape = new EllipseStylusShape(boundWidth, boundWidth);
|
||||
inkCanvas.EditingMode = InkCanvasEditingMode.EraseByPoint;
|
||||
isPalmEraserActive = true;
|
||||
|
||||
|
||||
// 启用橡皮擦覆盖层显示手掌擦样式
|
||||
EnableEraserOverlay();
|
||||
// 更新橡皮擦大小以匹配手掌擦面积
|
||||
@@ -746,7 +743,7 @@ namespace Ink_Canvas
|
||||
{
|
||||
isMultiTouchTimerActive = true;
|
||||
var remainingTime = MULTI_TOUCH_DELAY_MS - timeSinceLastTouch;
|
||||
System.Threading.Tasks.Task.Delay((int)remainingTime).ContinueWith(_ =>
|
||||
System.Threading.Tasks.Task.Delay((int)remainingTime).ContinueWith(_ =>
|
||||
{
|
||||
Dispatcher.Invoke(() =>
|
||||
{
|
||||
@@ -760,7 +757,7 @@ namespace Ink_Canvas
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
lastInkCanvasEditingMode = inkCanvas.EditingMode;
|
||||
if (inkCanvas.EditingMode != InkCanvasEditingMode.EraseByPoint
|
||||
&& inkCanvas.EditingMode != InkCanvasEditingMode.EraseByStroke
|
||||
@@ -773,7 +770,7 @@ namespace Ink_Canvas
|
||||
|
||||
private void inkCanvas_PreviewTouchMove(object sender, TouchEventArgs e)
|
||||
{
|
||||
|
||||
|
||||
// 如果手掌擦激活,更新橡皮擦反馈位置
|
||||
if (isPalmEraserActive)
|
||||
{
|
||||
@@ -795,71 +792,19 @@ namespace Ink_Canvas
|
||||
|
||||
// Palm Eraser 逻辑
|
||||
dec.Remove(e.TouchDevice.Id);
|
||||
|
||||
|
||||
// 重置多触控点定时器状态
|
||||
if (dec.Count <= 1)
|
||||
{
|
||||
isMultiTouchTimerActive = false;
|
||||
}
|
||||
|
||||
|
||||
// 当手掌擦激活且所有触摸点都抬起时,恢复原编辑模式
|
||||
if (isPalmEraserActive && dec.Count == 0)
|
||||
{
|
||||
LogHelper.WriteLogToFile($"Palm eraser recovery triggered - Touch points remaining: {dec.Count}");
|
||||
|
||||
// 恢复高光状态
|
||||
drawingAttributes.IsHighlighter = palmEraserLastIsHighlighter;
|
||||
|
||||
// 恢复编辑模式
|
||||
try
|
||||
{
|
||||
if (inkCanvas.EditingMode == InkCanvasEditingMode.EraseByPoint)
|
||||
{
|
||||
// 根据之前的状态恢复
|
||||
switch (palmEraserLastEditingMode)
|
||||
{
|
||||
case InkCanvasEditingMode.Ink:
|
||||
PenIcon_Click(null, null);
|
||||
break;
|
||||
case InkCanvasEditingMode.Select:
|
||||
SymbolIconSelect_MouseUp(null, null);
|
||||
break;
|
||||
default:
|
||||
inkCanvas.EditingMode = palmEraserLastEditingMode;
|
||||
break;
|
||||
}
|
||||
|
||||
LogHelper.WriteLogToFile($"Palm eraser recovered to mode: {palmEraserLastEditingMode}");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// 如果恢复失败,强制切换到批注模式
|
||||
LogHelper.WriteLogToFile($"Palm eraser recovery failed: {ex.Message}, forcing to Ink mode", LogHelper.LogType.Error);
|
||||
inkCanvas.EditingMode = InkCanvasEditingMode.Ink;
|
||||
}
|
||||
|
||||
// 重置手掌擦状态
|
||||
isPalmEraserActive = false;
|
||||
|
||||
// 禁用橡皮擦覆盖层
|
||||
DisableEraserOverlay();
|
||||
if (Settings.Canvas.IsShowCursor)
|
||||
{
|
||||
inkCanvas.ForceCursor = true;
|
||||
inkCanvas.UseCustomCursor = true;
|
||||
}
|
||||
|
||||
LogHelper.WriteLogToFile("Palm eraser state reset completed");
|
||||
}
|
||||
|
||||
if (drawingShapeMode != 0)
|
||||
{
|
||||
isTouchDown = false;
|
||||
ViewboxFloatingBar.IsHitTestVisible = true;
|
||||
BlackboardUIGridForInkReplay.IsHitTestVisible = true;
|
||||
|
||||
|
||||
// 对于双曲线等需要多步绘制的图形,触摸抬手时应该进入下一步
|
||||
if (drawingShapeMode == 24 || drawingShapeMode == 25)
|
||||
{
|
||||
@@ -917,7 +862,7 @@ namespace Ink_Canvas
|
||||
inkCanvas.EditingMode = lastInkCanvasEditingMode;
|
||||
}
|
||||
|
||||
if (isPalmEraserActive)
|
||||
if (isPalmEraserActive)
|
||||
{
|
||||
LogHelper.WriteLogToFile("Palm eraser force recovery - all touch points cleared");
|
||||
|
||||
@@ -1010,7 +955,7 @@ namespace Ink_Canvas
|
||||
bool disableScale = dec.Count >= 3;
|
||||
|
||||
if (isInMultiTouchMode) return;
|
||||
|
||||
|
||||
if (dec.Count == 0 && (isSingleFingerDragMode || isInMultiTouchMode))
|
||||
{
|
||||
ResetTouchStates();
|
||||
@@ -1113,7 +1058,7 @@ namespace Ink_Canvas
|
||||
else
|
||||
{
|
||||
foreach (var stroke in inkCanvas.Strokes) stroke.Transform(m, false);
|
||||
|
||||
|
||||
// 同时变换画布上的图片元素
|
||||
TransformCanvasImages(m);
|
||||
}
|
||||
@@ -1144,7 +1089,7 @@ namespace Ink_Canvas
|
||||
for (int i = inkCanvas.Children.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var child = inkCanvas.Children[i];
|
||||
|
||||
|
||||
if (child is Image image)
|
||||
{
|
||||
// 应用矩阵变换到图片
|
||||
|
||||
@@ -209,15 +209,15 @@ namespace Ink_Canvas
|
||||
try
|
||||
{
|
||||
// 获取全局快捷键管理器
|
||||
var hotkeyManagerField = typeof(MainWindow).GetField("_globalHotkeyManager",
|
||||
var hotkeyManagerField = typeof(MainWindow).GetField("_globalHotkeyManager",
|
||||
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||
var hotkeyManager = hotkeyManagerField?.GetValue(mainWin) as GlobalHotkeyManager;
|
||||
|
||||
|
||||
if (hotkeyManager != null)
|
||||
{
|
||||
// 禁用所有快捷键
|
||||
hotkeyManager.DisableHotkeyRegistration();
|
||||
|
||||
|
||||
// 更新菜单项文本和状态
|
||||
var menuItem = sender as MenuItem;
|
||||
if (menuItem != null)
|
||||
|
||||
@@ -10,7 +10,7 @@ using System.Windows;
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("CJK_mkp")]
|
||||
[assembly: AssemblyProduct("InkCanvasForClass")]
|
||||
[assembly: AssemblyCopyright("Copyright © HARKOTEK Studio 2024")]
|
||||
[assembly: AssemblyCopyright("Copyright © CJK_mkp 2025")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
@@ -49,5 +49,5 @@ using System.Windows;
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.7.12.0")]
|
||||
[assembly: AssemblyFileVersion("1.7.12.0")]
|
||||
[assembly: AssemblyVersion("1.7.17.0")]
|
||||
[assembly: AssemblyFileVersion("1.7.17.0")]
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
-->
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Any CPU</Platform>
|
||||
<PublishDir>dist\</PublishDir>
|
||||
<PublishProtocol>FileSystem</PublishProtocol>
|
||||
<_TargetId>Folder</_TargetId>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
@@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
-->
|
||||
<Project>
|
||||
</Project>
|
||||
@@ -74,5 +74,14 @@ namespace Ink_Canvas.Properties {
|
||||
return ResourceManager.GetStream("TimerDownNotice", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.IO.UnmanagedMemoryStream similar to System.IO.MemoryStream.
|
||||
/// </summary>
|
||||
internal static UnmanagedMemoryStream ProgressiveAudio {
|
||||
get {
|
||||
return ResourceManager.GetStream("ProgressiveAudio", resourceCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,4 +121,7 @@
|
||||
<data name="TimerDownNotice" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\TimerDownNotice.wav;System.IO.MemoryStream, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="ProgressiveAudio" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\ProgressiveAudio.wav;System.IO.MemoryStream, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -1,100 +1,100 @@
|
||||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||
<SolidColorBrush x:Key="IconBrush" Color="White"></SolidColorBrush>
|
||||
<SolidColorBrush x:Key="IconBrush" Color="{DynamicResource IconForeground}"></SolidColorBrush>
|
||||
<DrawingImage x:Key="CursorIconV2">
|
||||
<DrawingImage.Drawing>
|
||||
<DrawingGroup ClipGeometry="M0,0 V24 H24 V0 H0 Z">
|
||||
<GeometryDrawing Brush="{StaticResource IconBrush}" Geometry="F1 M24,24z M0,0z M22.7989,10.1653L1.14304,1.14304 10.1653,22.7989 12.8305,14.9518 19.6892,21.8105 21.8105,19.6892 14.9518,12.8305 22.7989,10.1653z" />
|
||||
<GeometryDrawing Brush="{DynamicResource IconBrush}" Geometry="F1 M24,24z M0,0z M22.7989,10.1653L1.14304,1.14304 10.1653,22.7989 12.8305,14.9518 19.6892,21.8105 21.8105,19.6892 14.9518,12.8305 22.7989,10.1653z" />
|
||||
</DrawingGroup>
|
||||
</DrawingImage.Drawing>
|
||||
</DrawingImage>
|
||||
<DrawingImage x:Key="PenIconV2">
|
||||
<DrawingImage.Drawing>
|
||||
<DrawingGroup ClipGeometry="M0,0 V24 H24 V0 H0 Z">
|
||||
<GeometryDrawing Brush="{StaticResource IconBrush}" Geometry="F1 M24,24z M0,0z M20.4786,1.42438C19.9985,1.23743 19.4847,1.15194 18.9698,1.17319 18.4549,1.19444 17.9499,1.32197 17.4869,1.54789 17.0368,1.76752 16.6358,2.07554 16.3083,2.45361L3.85516,14.9067 9.08243,20.134 21.5311,7.68529C21.9113,7.36382 22.223,6.96912 22.447,6.52438 22.6786,6.06462 22.8113,5.56167 22.8365,5.04763 22.8616,4.5336 22.7787,4.02012 22.593,3.54002 22.4073,3.05994 22.1232,2.62403 21.759,2.25988 21.3949,1.89574 20.9587,1.61132 20.4786,1.42438z" />
|
||||
<GeometryDrawing Brush="{StaticResource IconBrush}" Geometry="F1 M24,24z M0,0z M7.28056,21.1605L2.8286,16.7086 1.15912,22.83 7.28056,21.1605z" />
|
||||
<GeometryDrawing Brush="{DynamicResource IconBrush}" Geometry="F1 M24,24z M0,0z M20.4786,1.42438C19.9985,1.23743 19.4847,1.15194 18.9698,1.17319 18.4549,1.19444 17.9499,1.32197 17.4869,1.54789 17.0368,1.76752 16.6358,2.07554 16.3083,2.45361L3.85516,14.9067 9.08243,20.134 21.5311,7.68529C21.9113,7.36382 22.223,6.96912 22.447,6.52438 22.6786,6.06462 22.8113,5.56167 22.8365,5.04763 22.8616,4.5336 22.7787,4.02012 22.593,3.54002 22.4073,3.05994 22.1232,2.62403 21.759,2.25988 21.3949,1.89574 20.9587,1.61132 20.4786,1.42438z" />
|
||||
<GeometryDrawing Brush="{DynamicResource IconBrush}" Geometry="F1 M24,24z M0,0z M7.28056,21.1605L2.8286,16.7086 1.15912,22.83 7.28056,21.1605z" />
|
||||
</DrawingGroup>
|
||||
</DrawingImage.Drawing>
|
||||
</DrawingImage>
|
||||
<DrawingImage x:Key="EraserIconV2">
|
||||
<DrawingImage.Drawing>
|
||||
<DrawingGroup ClipGeometry="M0,0 V24 H24 V0 H0 Z">
|
||||
<GeometryDrawing Brush="{StaticResource IconBrush}" Geometry="F1 M24,24z M0,0z M15.6314,20.7262L22.7921,13.5655C24.3494,12.141,24.2819,9.81776,22.8105,8.34633L16.7793,2.31508C15.3547,0.757753,13.0315,0.825236,11.5601,2.29666L4.38099,9.47574 15.6314,20.7262z" />
|
||||
<GeometryDrawing Brush="{StaticResource IconBrush}" Geometry="F1 M24,24z M0,0z M14.2172,22.1404L2.96677,10.89 1.20761,12.6491C-0.34971,14.0737,-0.281711,16.3974,1.18971,17.8688L6.15089,22.83 13.5276,22.83 14.2172,22.1404z" />
|
||||
<GeometryDrawing Brush="{DynamicResource IconBrush}" Geometry="F1 M24,24z M0,0z M15.6314,20.7262L22.7921,13.5655C24.3494,12.141,24.2819,9.81776,22.8105,8.34633L16.7793,2.31508C15.3547,0.757753,13.0315,0.825236,11.5601,2.29666L4.38099,9.47574 15.6314,20.7262z" />
|
||||
<GeometryDrawing Brush="{DynamicResource IconBrush}" Geometry="F1 M24,24z M0,0z M14.2172,22.1404L2.96677,10.89 1.20761,12.6491C-0.34971,14.0737,-0.281711,16.3974,1.18971,17.8688L6.15089,22.83 13.5276,22.83 14.2172,22.1404z" />
|
||||
</DrawingGroup>
|
||||
</DrawingImage.Drawing>
|
||||
</DrawingImage>
|
||||
<DrawingImage x:Key="TrashBinIconV2">
|
||||
<DrawingImage.Drawing>
|
||||
<DrawingGroup ClipGeometry="M0,0 V24 H24 V0 H0 Z">
|
||||
<GeometryDrawing Brush="{StaticResource IconBrush}" Geometry="F1 M24,24z M0,0z M2.15454,7.07729L2.15454,5.1082 7.07727,5.1082 7.07727,4.12365C7.07727,3.30648 7.47109,2.57791 7.98305,2.0758 8.49501,1.56383 9.22358,1.17001 10.0309,1.17001L13.9691,1.17001C14.7863,1.17001 15.5148,1.56383 16.0169,2.0758 16.5289,2.58776 16.9227,3.31632 16.9227,4.12365L16.9227,5.1082 21.8454,5.1082 21.8454,7.07729 2.15454,7.07729z" />
|
||||
<GeometryDrawing Brush="{StaticResource IconBrush}" Geometry="F0 M24,24z M0,0z M4.12363,19.7779C4.12363,20.6148 4.51745,21.3729 5.02941,21.8947 5.54138,22.4165 6.26994,22.83 7.07727,22.83L16.9227,22.83C17.7399,22.83 18.4685,22.4165 18.9706,21.8947 19.4825,21.3729 19.8764,20.6148 19.8764,19.7779L19.8764,8.06183 4.12363,8.06183 4.12363,19.7779z M12.9845,11.0155L14.9536,11.0155 14.9536,18.8918 12.9845,18.8918 12.9845,11.0155z M9.04636,11.0155L11.0154,11.0155 11.0154,18.8918 9.04636,18.8918 9.04636,11.0155z" />
|
||||
<GeometryDrawing Brush="{DynamicResource IconBrush}" Geometry="F1 M24,24z M0,0z M2.15454,7.07729L2.15454,5.1082 7.07727,5.1082 7.07727,4.12365C7.07727,3.30648 7.47109,2.57791 7.98305,2.0758 8.49501,1.56383 9.22358,1.17001 10.0309,1.17001L13.9691,1.17001C14.7863,1.17001 15.5148,1.56383 16.0169,2.0758 16.5289,2.58776 16.9227,3.31632 16.9227,4.12365L16.9227,5.1082 21.8454,5.1082 21.8454,7.07729 2.15454,7.07729z" />
|
||||
<GeometryDrawing Brush="{DynamicResource IconBrush}" Geometry="F0 M24,24z M0,0z M4.12363,19.7779C4.12363,20.6148 4.51745,21.3729 5.02941,21.8947 5.54138,22.4165 6.26994,22.83 7.07727,22.83L16.9227,22.83C17.7399,22.83 18.4685,22.4165 18.9706,21.8947 19.4825,21.3729 19.8764,20.6148 19.8764,19.7779L19.8764,8.06183 4.12363,8.06183 4.12363,19.7779z M12.9845,11.0155L14.9536,11.0155 14.9536,18.8918 12.9845,18.8918 12.9845,11.0155z M9.04636,11.0155L11.0154,11.0155 11.0154,18.8918 9.04636,18.8918 9.04636,11.0155z" />
|
||||
</DrawingGroup>
|
||||
</DrawingImage.Drawing>
|
||||
</DrawingImage>
|
||||
<DrawingImage x:Key="LassoSelectIconV2">
|
||||
<DrawingImage.Drawing>
|
||||
<DrawingGroup ClipGeometry="M0,0 V24 H24 V0 H0 Z">
|
||||
<GeometryDrawing Brush="{StaticResource IconBrush}" Geometry="F1 M24,24z M0,0z M2.12162,2.12162C2.73093,1.51232,3.55732,1.17001,4.41901,1.17001L5.50201,1.17001 5.50201,3.33601 4.41901,3.33601C4.13178,3.33601 3.85632,3.45011 3.65321,3.65321 3.45011,3.85632 3.33601,4.13178 3.33601,4.41901L3.33601,5.50201 1.17001,5.50201 1.17001,4.41901C1.17001,3.55732,1.51232,2.73093,2.12162,2.12162z" />
|
||||
<GeometryDrawing Brush="{StaticResource IconBrush}" Geometry="F1 M24,24z M0,0z M18.498,1.17001L19.581,1.17001C20.4427,1.17001 21.2691,1.51232 21.8784,2.12162 22.4877,2.73093 22.83,3.55732 22.83,4.41901L22.83,5.50201 20.664,5.50201 20.664,4.41901C20.664,4.13178 20.5499,3.85632 20.3468,3.65321 20.1437,3.45011 19.8682,3.33601 19.581,3.33601L18.498,3.33601 18.498,1.17001z" />
|
||||
<GeometryDrawing Brush="{StaticResource IconBrush}" Geometry="F1 M24,24z M0,0z M3.33601,19.581L3.33601,18.498 1.17001,18.498 1.17001,19.581C1.17001,20.4427 1.51232,21.2691 2.12162,21.8784 2.73093,22.4877 3.55732,22.83 4.41901,22.83L5.50201,22.83 5.50201,20.664 4.41901,20.664C4.13178,20.664 3.85632,20.5499 3.65321,20.3468 3.45011,20.1437 3.33601,19.8682 3.33601,19.581z" />
|
||||
<GeometryDrawing Brush="{StaticResource IconBrush}" Geometry="F1 M24,24z M0,0z M7.66801,1.17001L10.917,1.17001 10.917,3.33601 7.66801,3.33601 7.66801,1.17001z" />
|
||||
<GeometryDrawing Brush="{StaticResource IconBrush}" Geometry="F1 M24,24z M0,0z M12,20.664L7.66801,20.664 7.66801,22.83 12,22.83 12,20.664z" />
|
||||
<GeometryDrawing Brush="{StaticResource IconBrush}" Geometry="F1 M24,24z M0,0z M13.083,1.17001L16.332,1.17001 16.332,3.33601 13.083,3.33601 13.083,1.17001z" />
|
||||
<GeometryDrawing Brush="{StaticResource IconBrush}" Geometry="F1 M24,24z M0,0z M3.33601,10.917L3.33601,7.66801 1.17001,7.66801 1.17001,10.917 3.33601,10.917z" />
|
||||
<GeometryDrawing Brush="{StaticResource IconBrush}" Geometry="F1 M24,24z M0,0z M22.83,7.66801L22.83,12 20.664,12 20.664,7.66801 22.83,7.66801z" />
|
||||
<GeometryDrawing Brush="{StaticResource IconBrush}" Geometry="F1 M24,24z M0,0z M3.33601,16.332L3.33601,13.083 1.17001,13.083 1.17001,16.332 3.33601,16.332z" />
|
||||
<GeometryDrawing Brush="{StaticResource IconBrush}" Geometry="F1 M24,24z M0,0z M10.7469,10.747L22.83,15.781 18.4517,17.2681 22.2785,21.0949 21.0949,22.2785 17.2681,18.4517 15.781,22.83 10.7469,10.747z" />
|
||||
<GeometryDrawing Brush="{DynamicResource IconBrush}" Geometry="F1 M24,24z M0,0z M2.12162,2.12162C2.73093,1.51232,3.55732,1.17001,4.41901,1.17001L5.50201,1.17001 5.50201,3.33601 4.41901,3.33601C4.13178,3.33601 3.85632,3.45011 3.65321,3.65321 3.45011,3.85632 3.33601,4.13178 3.33601,4.41901L3.33601,5.50201 1.17001,5.50201 1.17001,4.41901C1.17001,3.55732,1.51232,2.73093,2.12162,2.12162z" />
|
||||
<GeometryDrawing Brush="{DynamicResource IconBrush}" Geometry="F1 M24,24z M0,0z M18.498,1.17001L19.581,1.17001C20.4427,1.17001 21.2691,1.51232 21.8784,2.12162 22.4877,2.73093 22.83,3.55732 22.83,4.41901L22.83,5.50201 20.664,5.50201 20.664,4.41901C20.664,4.13178 20.5499,3.85632 20.3468,3.65321 20.1437,3.45011 19.8682,3.33601 19.581,3.33601L18.498,3.33601 18.498,1.17001z" />
|
||||
<GeometryDrawing Brush="{DynamicResource IconBrush}" Geometry="F1 M24,24z M0,0z M3.33601,19.581L3.33601,18.498 1.17001,18.498 1.17001,19.581C1.17001,20.4427 1.51232,21.2691 2.12162,21.8784 2.73093,22.4877 3.55732,22.83 4.41901,22.83L5.50201,22.83 5.50201,20.664 4.41901,20.664C4.13178,20.664 3.85632,20.5499 3.65321,20.3468 3.45011,20.1437 3.33601,19.8682 3.33601,19.581z" />
|
||||
<GeometryDrawing Brush="{DynamicResource IconBrush}" Geometry="F1 M24,24z M0,0z M7.66801,1.17001L10.917,1.17001 10.917,3.33601 7.66801,3.33601 7.66801,1.17001z" />
|
||||
<GeometryDrawing Brush="{DynamicResource IconBrush}" Geometry="F1 M24,24z M0,0z M12,20.664L7.66801,20.664 7.66801,22.83 12,22.83 12,20.664z" />
|
||||
<GeometryDrawing Brush="{DynamicResource IconBrush}" Geometry="F1 M24,24z M0,0z M13.083,1.17001L16.332,1.17001 16.332,3.33601 13.083,3.33601 13.083,1.17001z" />
|
||||
<GeometryDrawing Brush="{DynamicResource IconBrush}" Geometry="F1 M24,24z M0,0z M3.33601,10.917L3.33601,7.66801 1.17001,7.66801 1.17001,10.917 3.33601,10.917z" />
|
||||
<GeometryDrawing Brush="{DynamicResource IconBrush}" Geometry="F1 M24,24z M0,0z M22.83,7.66801L22.83,12 20.664,12 20.664,7.66801 22.83,7.66801z" />
|
||||
<GeometryDrawing Brush="{DynamicResource IconBrush}" Geometry="F1 M24,24z M0,0z M3.33601,16.332L3.33601,13.083 1.17001,13.083 1.17001,16.332 3.33601,16.332z" />
|
||||
<GeometryDrawing Brush="{DynamicResource IconBrush}" Geometry="F1 M24,24z M0,0z M10.7469,10.747L22.83,15.781 18.4517,17.2681 22.2785,21.0949 21.0949,22.2785 17.2681,18.4517 15.781,22.83 10.7469,10.747z" />
|
||||
</DrawingGroup>
|
||||
</DrawingImage.Drawing>
|
||||
</DrawingImage>
|
||||
<DrawingImage x:Key="ShapesIconV2">
|
||||
<DrawingImage.Drawing>
|
||||
<DrawingGroup ClipGeometry="M0,0 V24 H24 V0 H0 Z">
|
||||
<GeometryDrawing Brush="{StaticResource IconBrush}" Geometry="F1 M24,24z M0,0z M17.8604,10.7597L12.0068,1.17001 6.13961,10.7597 17.8604,10.7597z" />
|
||||
<GeometryDrawing Brush="{StaticResource IconBrush}" Geometry="F1 M24,24z M0,0z M10.9345,13.2403L1.34476,13.2403 1.34476,22.83 10.9345,22.83 10.9345,13.2403z" />
|
||||
<GeometryDrawing Brush="{StaticResource IconBrush}" Geometry="F1 M24,24z M0,0z M17.8604,13.2403C15.2122,13.2403 13.0655,15.387 13.0655,18.0352 13.0655,20.6833 15.2122,22.83 17.8604,22.83 20.5085,22.83 22.6552,20.6833 22.6552,18.0352 22.6552,15.387 20.5085,13.2403 17.8604,13.2403z" />
|
||||
<GeometryDrawing Brush="{DynamicResource IconBrush}" Geometry="F1 M24,24z M0,0z M17.8604,10.7597L12.0068,1.17001 6.13961,10.7597 17.8604,10.7597z" />
|
||||
<GeometryDrawing Brush="{DynamicResource IconBrush}" Geometry="F1 M24,24z M0,0z M10.9345,13.2403L1.34476,13.2403 1.34476,22.83 10.9345,22.83 10.9345,13.2403z" />
|
||||
<GeometryDrawing Brush="{DynamicResource IconBrush}" Geometry="F1 M24,24z M0,0z M17.8604,13.2403C15.2122,13.2403 13.0655,15.387 13.0655,18.0352 13.0655,20.6833 15.2122,22.83 17.8604,22.83 20.5085,22.83 22.6552,20.6833 22.6552,18.0352 22.6552,15.387 20.5085,13.2403 17.8604,13.2403z" />
|
||||
</DrawingGroup>
|
||||
</DrawingImage.Drawing>
|
||||
</DrawingImage>
|
||||
<DrawingImage x:Key="UndoIconV2">
|
||||
<DrawingImage.Drawing>
|
||||
<DrawingGroup ClipGeometry="M0,0 V24 H24 V0 H0 Z">
|
||||
<GeometryDrawing Brush="{StaticResource IconBrush}" Geometry="F1 M24,24z M0,0z M8.71408,16.8493L0.874451,9.00964 8.71408,1.17001 8.71408,7.42358 15.7239,7.42358C16.7074,7.42358 17.6791,7.62744 18.583,8.02124 19.4866,8.41493 20.3023,8.98966 20.9857,9.70849 21.6689,10.4271 22.2069,11.276 22.5726,12.2047 22.9383,13.1333 23.1256,14.126 23.1256,15.1268 23.1256,16.1276 22.9383,17.1203 22.5726,18.0489 22.2069,18.9776 21.6689,19.8264 20.9857,20.5451 20.3023,21.2639 19.4866,21.8387 18.583,22.2324 17.6791,22.6262 16.7074,22.83 15.7239,22.83L10.437,22.83 10.437,19.6579 15.7239,19.6579C16.2679,19.6579 16.8086,19.5453 17.3159,19.3243 17.8235,19.1031 18.29,18.7767 18.6867,18.3594 19.0835,17.942 19.4023,17.4422 19.6211,16.8866 19.8399,16.3308 19.9534,15.7326 19.9534,15.1268 19.9534,14.5209 19.8399,13.9227 19.6211,13.367 19.4023,12.8114 19.0835,12.3115 18.6867,11.8941 18.29,11.4769 17.8235,11.1505 17.3159,10.9293 16.8086,10.7083 16.2679,10.5957 15.7239,10.5957L8.71408,10.5957 8.71408,16.8493z" />
|
||||
<GeometryDrawing Brush="{DynamicResource IconBrush}" Geometry="F1 M24,24z M0,0z M8.71408,16.8493L0.874451,9.00964 8.71408,1.17001 8.71408,7.42358 15.7239,7.42358C16.7074,7.42358 17.6791,7.62744 18.583,8.02124 19.4866,8.41493 20.3023,8.98966 20.9857,9.70849 21.6689,10.4271 22.2069,11.276 22.5726,12.2047 22.9383,13.1333 23.1256,14.126 23.1256,15.1268 23.1256,16.1276 22.9383,17.1203 22.5726,18.0489 22.2069,18.9776 21.6689,19.8264 20.9857,20.5451 20.3023,21.2639 19.4866,21.8387 18.583,22.2324 17.6791,22.6262 16.7074,22.83 15.7239,22.83L10.437,22.83 10.437,19.6579 15.7239,19.6579C16.2679,19.6579 16.8086,19.5453 17.3159,19.3243 17.8235,19.1031 18.29,18.7767 18.6867,18.3594 19.0835,17.942 19.4023,17.4422 19.6211,16.8866 19.8399,16.3308 19.9534,15.7326 19.9534,15.1268 19.9534,14.5209 19.8399,13.9227 19.6211,13.367 19.4023,12.8114 19.0835,12.3115 18.6867,11.8941 18.29,11.4769 17.8235,11.1505 17.3159,10.9293 16.8086,10.7083 16.2679,10.5957 15.7239,10.5957L8.71408,10.5957 8.71408,16.8493z" />
|
||||
</DrawingGroup>
|
||||
</DrawingImage.Drawing>
|
||||
</DrawingImage>
|
||||
<DrawingImage x:Key="RedoIconV2">
|
||||
<DrawingImage.Drawing>
|
||||
<DrawingGroup ClipGeometry="M0,0 V24 H24 V0 H0 Z">
|
||||
<GeometryDrawing Brush="{StaticResource IconBrush}" Geometry="F1 M24,24z M0,0z M15.2859,16.8493L23.1255,9.00964 15.2859,1.17001 15.2859,7.42358 8.27607,7.42358C7.29262,7.42358 6.32086,7.62744 5.41703,8.02124 4.51341,8.41493 3.69773,8.98966 3.01434,9.70849 2.33111,10.4271 1.79312,11.276 1.42741,12.2047 1.06174,13.1333 0.874422,14.126 0.874422,15.1268 0.874422,16.1276 1.06174,17.1203 1.42741,18.0489 1.79312,18.9776 2.33111,19.8264 3.01434,20.5451 3.69773,21.2639 4.51341,21.8387 5.41703,22.2324 6.32086,22.6262 7.29262,22.83 8.27607,22.83L13.563,22.83 13.563,19.6579 8.27607,19.6579C7.7321,19.6579 7.19139,19.5453 6.68406,19.3243 6.17652,19.1031 5.70999,18.7767 5.31333,18.3594 4.91651,17.942 4.59775,17.4422 4.37894,16.8866 4.1601,16.3308 4.04656,15.7326 4.04656,15.1268 4.04656,14.5209 4.1601,13.9227 4.37894,13.367 4.59775,12.8114 4.91651,12.3115 5.31333,11.8941 5.70999,11.4769 6.17652,11.1505 6.68406,10.9293 7.19139,10.7083 7.7321,10.5957 8.27607,10.5957L15.2859,10.5957 15.2859,16.8493z" />
|
||||
<GeometryDrawing Brush="{DynamicResource IconBrush}" Geometry="F1 M24,24z M0,0z M15.2859,16.8493L23.1255,9.00964 15.2859,1.17001 15.2859,7.42358 8.27607,7.42358C7.29262,7.42358 6.32086,7.62744 5.41703,8.02124 4.51341,8.41493 3.69773,8.98966 3.01434,9.70849 2.33111,10.4271 1.79312,11.276 1.42741,12.2047 1.06174,13.1333 0.874422,14.126 0.874422,15.1268 0.874422,16.1276 1.06174,17.1203 1.42741,18.0489 1.79312,18.9776 2.33111,19.8264 3.01434,20.5451 3.69773,21.2639 4.51341,21.8387 5.41703,22.2324 6.32086,22.6262 7.29262,22.83 8.27607,22.83L13.563,22.83 13.563,19.6579 8.27607,19.6579C7.7321,19.6579 7.19139,19.5453 6.68406,19.3243 6.17652,19.1031 5.70999,18.7767 5.31333,18.3594 4.91651,17.942 4.59775,17.4422 4.37894,16.8866 4.1601,16.3308 4.04656,15.7326 4.04656,15.1268 4.04656,14.5209 4.1601,13.9227 4.37894,13.367 4.59775,12.8114 4.91651,12.3115 5.31333,11.8941 5.70999,11.4769 6.17652,11.1505 6.68406,10.9293 7.19139,10.7083 7.7321,10.5957 8.27607,10.5957L15.2859,10.5957 15.2859,16.8493z" />
|
||||
</DrawingGroup>
|
||||
</DrawingImage.Drawing>
|
||||
</DrawingImage>
|
||||
<DrawingImage x:Key="MoreToolsIconV2">
|
||||
<DrawingImage.Drawing>
|
||||
<DrawingGroup ClipGeometry="M0,0 V24 H24 V0 H0 Z">
|
||||
<GeometryDrawing Brush="{StaticResource IconBrush}" Geometry="F1 M24,24z M0,0z M3.336,1.17001C2.13975,1.17001,1.17,2.13976,1.17,3.33601L1.17,8.75101C1.17,9.94726,2.13975,10.917,3.336,10.917L8.751,10.917C9.94725,10.917,10.917,9.94726,10.917,8.75101L10.917,3.33601C10.917,2.13976,9.94725,1.17001,8.751,1.17001L3.336,1.17001z" />
|
||||
<GeometryDrawing Brush="{StaticResource IconBrush}" Geometry="F1 M24,24z M0,0z M15.249,1.17001C14.0527,1.17001,13.083,2.13976,13.083,3.33601L13.083,8.75101C13.083,9.94726,14.0527,10.917,15.249,10.917L20.664,10.917C21.8602,10.917,22.83,9.94726,22.83,8.75101L22.83,3.33601C22.83,2.13976,21.8602,1.17001,20.664,1.17001L15.249,1.17001z" />
|
||||
<GeometryDrawing Brush="{StaticResource IconBrush}" Geometry="F1 M24,24z M0,0z M3.336,13.083C2.13975,13.083,1.17,14.0528,1.17,15.249L1.17,20.664C1.17,21.8603,2.13975,22.83,3.336,22.83L8.751,22.83C9.94725,22.83,10.917,21.8603,10.917,20.664L10.917,15.249C10.917,14.0528,9.94725,13.083,8.751,13.083L3.336,13.083z" />
|
||||
<GeometryDrawing Brush="{StaticResource IconBrush}" Geometry="F1 M24,24z M0,0z M15.249,13.083C14.0527,13.083,13.083,14.0528,13.083,15.249L13.083,20.664C13.083,21.8603,14.0527,22.83,15.249,22.83L20.664,22.83C21.8602,22.83,22.83,21.8603,22.83,20.664L22.83,15.249C22.83,14.0528,21.8602,13.083,20.664,13.083L15.249,13.083z" />
|
||||
<GeometryDrawing Brush="{DynamicResource IconBrush}" Geometry="F1 M24,24z M0,0z M3.336,1.17001C2.13975,1.17001,1.17,2.13976,1.17,3.33601L1.17,8.75101C1.17,9.94726,2.13975,10.917,3.336,10.917L8.751,10.917C9.94725,10.917,10.917,9.94726,10.917,8.75101L10.917,3.33601C10.917,2.13976,9.94725,1.17001,8.751,1.17001L3.336,1.17001z" />
|
||||
<GeometryDrawing Brush="{DynamicResource IconBrush}" Geometry="F1 M24,24z M0,0z M15.249,1.17001C14.0527,1.17001,13.083,2.13976,13.083,3.33601L13.083,8.75101C13.083,9.94726,14.0527,10.917,15.249,10.917L20.664,10.917C21.8602,10.917,22.83,9.94726,22.83,8.75101L22.83,3.33601C22.83,2.13976,21.8602,1.17001,20.664,1.17001L15.249,1.17001z" />
|
||||
<GeometryDrawing Brush="{DynamicResource IconBrush}" Geometry="F1 M24,24z M0,0z M3.336,13.083C2.13975,13.083,1.17,14.0528,1.17,15.249L1.17,20.664C1.17,21.8603,2.13975,22.83,3.336,22.83L8.751,22.83C9.94725,22.83,10.917,21.8603,10.917,20.664L10.917,15.249C10.917,14.0528,9.94725,13.083,8.751,13.083L3.336,13.083z" />
|
||||
<GeometryDrawing Brush="{DynamicResource IconBrush}" Geometry="F1 M24,24z M0,0z M15.249,13.083C14.0527,13.083,13.083,14.0528,13.083,15.249L13.083,20.664C13.083,21.8603,14.0527,22.83,15.249,22.83L20.664,22.83C21.8602,22.83,22.83,21.8603,22.83,20.664L22.83,15.249C22.83,14.0528,21.8602,13.083,20.664,13.083L15.249,13.083z" />
|
||||
</DrawingGroup>
|
||||
</DrawingImage.Drawing>
|
||||
</DrawingImage>
|
||||
<DrawingImage x:Key="GestureIconV2">
|
||||
<DrawingImage.Drawing>
|
||||
<DrawingGroup ClipGeometry="M0,0 V24 H24 V0 H0 Z">
|
||||
<GeometryDrawing Brush="{StaticResource IconBrush}" Geometry="F0 M24,24z M0,0z M7.82154,10.0753L7.82154,3.74613C7.82154,3.06604 8.08946,2.40655 8.57377,1.92224 9.05808,1.43793 9.70726,1.17001 10.3977,1.17001 11.0881,1.17001 11.7372,1.43793 12.2216,1.92224 12.7059,2.40655 12.9738,3.05573 12.9738,3.74613L12.9738,6.37308C13.1415,6.33947 13.3139,6.32225 13.489,6.32225 14.1794,6.32225 14.8286,6.59016 15.3129,7.07447 15.4484,7.21001 15.567,7.35845 15.6675,7.5171 15.9551,7.40916 16.2634,7.35269 16.5803,7.35269 17.2707,7.35269 17.9199,7.62061 18.4042,8.10492 18.5461,8.24683 18.6695,8.4029 18.7729,8.57001 19.6856,8.26338 20.7674,8.45871 21.4647,9.15599 21.949,9.6403 22.2169,10.2998 22.2169,10.9799L22.2169,15.6169C22.2169,17.5438 21.4647,19.3574 20.1045,20.7176 18.7443,22.0778 16.9307,22.83 15.0038,22.83L13.149,22.83 13.1799,22.8094 12.8398,22.8094C11.7682,22.7579 10.7068,22.4694 9.75878,21.9541 8.70773,21.3874 7.81124,20.563 7.15175,19.5738L6.94566,19.2647C6.60562,18.7494 5.49273,16.8019 3.52458,13.3087 3.19484,12.7213 3.1021,12.0412 3.27727,11.3818 3.45245,10.7326 3.86463,10.1761 4.44168,9.83608 5.00842,9.49604 5.66791,9.35177 6.31709,9.43421 6.86548,9.50385 7.39181,9.7279 7.82154,10.0753z M10.037,3.38547C10.1297,3.28243 10.2637,3.23091 10.3977,3.23091 10.5316,3.23091 10.6656,3.29273 10.7583,3.38547 10.8614,3.47821 10.9129,3.61217 10.9129,3.74613L10.9129,11.4745C10.9129,12.0412 11.3766,12.5049 11.9433,12.5049 12.5101,12.5049 12.9738,12.0412 12.9738,11.4745L12.9738,8.89836C12.9738,8.7644 13.0356,8.63045 13.1283,8.53771 13.2211,8.43466 13.355,8.38314 13.489,8.38314 13.623,8.38314 13.7569,8.44497 13.8497,8.53771 13.9527,8.63045 14.0042,8.7644 14.0042,8.89836L14.0042,11.4745C14.0042,12.0412 14.4679,12.5049 15.0347,12.5049 15.6014,12.5049 16.0651,12.0412 16.0651,11.4745L16.0651,9.92881C16.0651,9.79485 16.1269,9.66089 16.2197,9.56815 16.3124,9.46511 16.4464,9.41359 16.5803,9.41359 16.7143,9.41359 16.8483,9.47541 16.941,9.56815 17.044,9.66089 17.0956,9.79485 17.0956,9.92881L17.0956,10.5869C17.0752,10.7163 17.0646,10.8477 17.0646,10.9799 17.0646,11.0661 17.0754,11.1499 17.0956,11.2301L17.0956,11.4745C17.0956,12.0412 17.5593,12.5049 18.126,12.5049 18.6928,12.5049 19.1565,12.0412 19.1565,11.4745L19.1565,10.8128C19.1834,10.7399 19.2266,10.6727 19.2801,10.6192 19.4759,10.4234 19.8159,10.4234 20.0117,10.6192 20.1148,10.712 20.1663,10.8459 20.1663,10.9799L20.1663,15.6169C20.1663,16.9977 19.6408,18.296 18.6618,19.2647 17.6829,20.2333 16.3949,20.7691 15.0141,20.7691L13.1593,20.7691C12.3143,20.7691 11.4796,20.5527 10.7274,20.1509 9.98548,19.749 9.3363,19.1616 8.8726,18.4506L8.66651,18.1415C8.35738,17.6675 7.23419,15.7096 5.31756,12.2989 5.24543,12.1752 5.23512,12.0412 5.26604,11.9073 5.30725,11.7733 5.38969,11.6703 5.50304,11.5981 5.66791,11.4951 5.874,11.4539 6.06978,11.4745 6.26557,11.5054 6.45105,11.5878 6.59531,11.7321L8.11007,13.2469C8.49419,13.631 9.10425,13.648 9.50833,13.2978 9.73651,13.1084 9.88244,12.8229 9.88244,12.5049L9.88244,3.74613C9.88244,3.61217,9.94426,3.47821,10.037,3.38547z" />
|
||||
<GeometryDrawing Brush="{StaticResource IconBrush}" Geometry="F1 M24,24z M0,0z M2.99905,6.31195L1.78313,4.65293 2.61779,4.04497C3.46275,3.4267,4.37985,2.89087,5.33817,2.46838L6.27587,2.0459 7.12084,3.93162 6.18313,4.3541C5.35878,4.72506,4.56533,5.17846,3.83372,5.71429L2.99905,6.32225 2.99905,6.31195z" />
|
||||
<GeometryDrawing Brush="{StaticResource IconBrush}" Geometry="F1 M24,24z M0,0z M18.2806,5.20935L19.1565,5.75549 20.259,4.01404 19.3832,3.4679C18.1157,2.67446,16.7452,2.0768,15.3026,1.68523L14.303,1.41731 13.7672,3.40607 14.7667,3.67399C16.0033,4.00373,17.1883,4.51895,18.2806,5.20935z" />
|
||||
<GeometryDrawing Brush="{DynamicResource IconBrush}" Geometry="F0 M24,24z M0,0z M7.82154,10.0753L7.82154,3.74613C7.82154,3.06604 8.08946,2.40655 8.57377,1.92224 9.05808,1.43793 9.70726,1.17001 10.3977,1.17001 11.0881,1.17001 11.7372,1.43793 12.2216,1.92224 12.7059,2.40655 12.9738,3.05573 12.9738,3.74613L12.9738,6.37308C13.1415,6.33947 13.3139,6.32225 13.489,6.32225 14.1794,6.32225 14.8286,6.59016 15.3129,7.07447 15.4484,7.21001 15.567,7.35845 15.6675,7.5171 15.9551,7.40916 16.2634,7.35269 16.5803,7.35269 17.2707,7.35269 17.9199,7.62061 18.4042,8.10492 18.5461,8.24683 18.6695,8.4029 18.7729,8.57001 19.6856,8.26338 20.7674,8.45871 21.4647,9.15599 21.949,9.6403 22.2169,10.2998 22.2169,10.9799L22.2169,15.6169C22.2169,17.5438 21.4647,19.3574 20.1045,20.7176 18.7443,22.0778 16.9307,22.83 15.0038,22.83L13.149,22.83 13.1799,22.8094 12.8398,22.8094C11.7682,22.7579 10.7068,22.4694 9.75878,21.9541 8.70773,21.3874 7.81124,20.563 7.15175,19.5738L6.94566,19.2647C6.60562,18.7494 5.49273,16.8019 3.52458,13.3087 3.19484,12.7213 3.1021,12.0412 3.27727,11.3818 3.45245,10.7326 3.86463,10.1761 4.44168,9.83608 5.00842,9.49604 5.66791,9.35177 6.31709,9.43421 6.86548,9.50385 7.39181,9.7279 7.82154,10.0753z M10.037,3.38547C10.1297,3.28243 10.2637,3.23091 10.3977,3.23091 10.5316,3.23091 10.6656,3.29273 10.7583,3.38547 10.8614,3.47821 10.9129,3.61217 10.9129,3.74613L10.9129,11.4745C10.9129,12.0412 11.3766,12.5049 11.9433,12.5049 12.5101,12.5049 12.9738,12.0412 12.9738,11.4745L12.9738,8.89836C12.9738,8.7644 13.0356,8.63045 13.1283,8.53771 13.2211,8.43466 13.355,8.38314 13.489,8.38314 13.623,8.38314 13.7569,8.44497 13.8497,8.53771 13.9527,8.63045 14.0042,8.7644 14.0042,8.89836L14.0042,11.4745C14.0042,12.0412 14.4679,12.5049 15.0347,12.5049 15.6014,12.5049 16.0651,12.0412 16.0651,11.4745L16.0651,9.92881C16.0651,9.79485 16.1269,9.66089 16.2197,9.56815 16.3124,9.46511 16.4464,9.41359 16.5803,9.41359 16.7143,9.41359 16.8483,9.47541 16.941,9.56815 17.044,9.66089 17.0956,9.79485 17.0956,9.92881L17.0956,10.5869C17.0752,10.7163 17.0646,10.8477 17.0646,10.9799 17.0646,11.0661 17.0754,11.1499 17.0956,11.2301L17.0956,11.4745C17.0956,12.0412 17.5593,12.5049 18.126,12.5049 18.6928,12.5049 19.1565,12.0412 19.1565,11.4745L19.1565,10.8128C19.1834,10.7399 19.2266,10.6727 19.2801,10.6192 19.4759,10.4234 19.8159,10.4234 20.0117,10.6192 20.1148,10.712 20.1663,10.8459 20.1663,10.9799L20.1663,15.6169C20.1663,16.9977 19.6408,18.296 18.6618,19.2647 17.6829,20.2333 16.3949,20.7691 15.0141,20.7691L13.1593,20.7691C12.3143,20.7691 11.4796,20.5527 10.7274,20.1509 9.98548,19.749 9.3363,19.1616 8.8726,18.4506L8.66651,18.1415C8.35738,17.6675 7.23419,15.7096 5.31756,12.2989 5.24543,12.1752 5.23512,12.0412 5.26604,11.9073 5.30725,11.7733 5.38969,11.6703 5.50304,11.5981 5.66791,11.4951 5.874,11.4539 6.06978,11.4745 6.26557,11.5054 6.45105,11.5878 6.59531,11.7321L8.11007,13.2469C8.49419,13.631 9.10425,13.648 9.50833,13.2978 9.73651,13.1084 9.88244,12.8229 9.88244,12.5049L9.88244,3.74613C9.88244,3.61217,9.94426,3.47821,10.037,3.38547z" />
|
||||
<GeometryDrawing Brush="{DynamicResource IconBrush}" Geometry="F1 M24,24z M0,0z M2.99905,6.31195L1.78313,4.65293 2.61779,4.04497C3.46275,3.4267,4.37985,2.89087,5.33817,2.46838L6.27587,2.0459 7.12084,3.93162 6.18313,4.3541C5.35878,4.72506,4.56533,5.17846,3.83372,5.71429L2.99905,6.32225 2.99905,6.31195z" />
|
||||
<GeometryDrawing Brush="{DynamicResource IconBrush}" Geometry="F1 M24,24z M0,0z M18.2806,5.20935L19.1565,5.75549 20.259,4.01404 19.3832,3.4679C18.1157,2.67446,16.7452,2.0768,15.3026,1.68523L14.303,1.41731 13.7672,3.40607 14.7667,3.67399C16.0033,4.00373,17.1883,4.51895,18.2806,5.20935z" />
|
||||
</DrawingGroup>
|
||||
</DrawingImage.Drawing>
|
||||
</DrawingImage>
|
||||
<DrawingImage x:Key="EyeOffIconV2">
|
||||
<DrawingImage.Drawing>
|
||||
<DrawingGroup ClipGeometry="M0,0 V24 H24 V0 H0 Z">
|
||||
<GeometryDrawing Brush="{StaticResource IconBrush}" Geometry="F0 M24,24z M0,0z M22.8347,21.5006L2.50417,1.17001 1.16525,2.50893 5.45737,6.80104C3.85257,8.10197 2.53265,9.72576 1.64954,11.5964 1.53559,11.8433 1.52609,12.1282 1.63055,12.3751L1.63055,12.3941C1.63055,12.4131 1.64954,12.4321 1.65904,12.4606 1.68752,12.5175 1.72551,12.5935 1.77299,12.698 1.87744,12.8974 2.01988,13.1822 2.21929,13.5146 2.61812,14.1793 3.21635,15.0719 4.04249,15.9645 5.69477,17.7497 8.30612,19.5919 11.981,19.5919 13.7282,19.5919 15.4375,19.1551 16.9568,18.31L21.4768,22.83 22.8158,21.4911 22.8347,21.5006z M11.9905,15.8791C12.5033,15.8696 13.0066,15.7556 13.4719,15.5467 13.6428,15.4707 13.7852,15.3758 13.9372,15.2808L8.72394,10.0676C8.62898,10.2195 8.53402,10.3715 8.45805,10.5329 8.24915,10.9982 8.1257,11.5015 8.1257,12.0143 8.1162,12.527 8.21116,13.0303 8.40108,13.5051 8.591,13.9799 8.87587,14.4072 9.23671,14.768 9.59755,15.1289 10.0249,15.4138 10.4997,15.6037 10.9745,15.7936 11.4777,15.8791 11.9905,15.8791z" />
|
||||
<GeometryDrawing Brush="{StaticResource IconBrush}" Geometry="F1 M24,24z M0,0z M10.9063,6.37657C11.2749,6.33269 11.6452,6.30726 12,6.30726 14.974,6.30726 17.1134,7.78595 18.5447,9.32737 19.2601,10.0978 19.7852,10.8712 20.1309,11.4519 20.2587,11.6665 20.3611,11.8535 20.4389,12.0025 20.0809,12.6966 19.6562,13.3505 19.1703,13.9543L18.5749,14.694 20.0544,15.8848 20.6498,15.145C21.3248,14.3064 21.8966,13.387 22.3556,12.4078 22.4706,12.1625 22.475,11.8789 22.3683,11.6299L22.3669,11.6266 22.364,11.6201 22.3551,11.5998C22.3477,11.5833 22.3375,11.5605 22.3243,11.5319 22.2979,11.4748 22.2598,11.3946 22.2098,11.2945 22.1097,11.0944 21.9615,10.8142 21.7628,10.4805 21.3666,9.81482 20.7641,8.92644 19.9364,8.03508 18.2816,6.25295 15.6731,4.4081 12,4.4081 11.5572,4.4081 11.1108,4.43965 10.6818,4.49072L9.73885,4.60297 9.96336,6.48883 10.9063,6.37657z" />
|
||||
<GeometryDrawing Brush="{DynamicResource IconBrush}" Geometry="F0 M24,24z M0,0z M22.8347,21.5006L2.50417,1.17001 1.16525,2.50893 5.45737,6.80104C3.85257,8.10197 2.53265,9.72576 1.64954,11.5964 1.53559,11.8433 1.52609,12.1282 1.63055,12.3751L1.63055,12.3941C1.63055,12.4131 1.64954,12.4321 1.65904,12.4606 1.68752,12.5175 1.72551,12.5935 1.77299,12.698 1.87744,12.8974 2.01988,13.1822 2.21929,13.5146 2.61812,14.1793 3.21635,15.0719 4.04249,15.9645 5.69477,17.7497 8.30612,19.5919 11.981,19.5919 13.7282,19.5919 15.4375,19.1551 16.9568,18.31L21.4768,22.83 22.8158,21.4911 22.8347,21.5006z M11.9905,15.8791C12.5033,15.8696 13.0066,15.7556 13.4719,15.5467 13.6428,15.4707 13.7852,15.3758 13.9372,15.2808L8.72394,10.0676C8.62898,10.2195 8.53402,10.3715 8.45805,10.5329 8.24915,10.9982 8.1257,11.5015 8.1257,12.0143 8.1162,12.527 8.21116,13.0303 8.40108,13.5051 8.591,13.9799 8.87587,14.4072 9.23671,14.768 9.59755,15.1289 10.0249,15.4138 10.4997,15.6037 10.9745,15.7936 11.4777,15.8791 11.9905,15.8791z" />
|
||||
<GeometryDrawing Brush="{DynamicResource IconBrush}" Geometry="F1 M24,24z M0,0z M10.9063,6.37657C11.2749,6.33269 11.6452,6.30726 12,6.30726 14.974,6.30726 17.1134,7.78595 18.5447,9.32737 19.2601,10.0978 19.7852,10.8712 20.1309,11.4519 20.2587,11.6665 20.3611,11.8535 20.4389,12.0025 20.0809,12.6966 19.6562,13.3505 19.1703,13.9543L18.5749,14.694 20.0544,15.8848 20.6498,15.145C21.3248,14.3064 21.8966,13.387 22.3556,12.4078 22.4706,12.1625 22.475,11.8789 22.3683,11.6299L22.3669,11.6266 22.364,11.6201 22.3551,11.5998C22.3477,11.5833 22.3375,11.5605 22.3243,11.5319 22.2979,11.4748 22.2598,11.3946 22.2098,11.2945 22.1097,11.0944 21.9615,10.8142 21.7628,10.4805 21.3666,9.81482 20.7641,8.92644 19.9364,8.03508 18.2816,6.25295 15.6731,4.4081 12,4.4081 11.5572,4.4081 11.1108,4.43965 10.6818,4.49072L9.73885,4.60297 9.96336,6.48883 10.9063,6.37657z" />
|
||||
</DrawingGroup>
|
||||
</DrawingImage.Drawing>
|
||||
</DrawingImage>
|
||||
|
||||
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 9.1 KiB |
|
After Width: | Height: | Size: 9.4 KiB |
|
Before Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 8.8 KiB |
|
After Width: | Height: | Size: 9.2 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 8.0 KiB |
|
After Width: | Height: | Size: 5.8 KiB |
|
After Width: | Height: | Size: 9.2 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 6.8 KiB |
|
After Width: | Height: | Size: 9.0 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 8.6 KiB |
|
After Width: | Height: | Size: 6.6 KiB |
|
After Width: | Height: | Size: 6.9 KiB |
|
After Width: | Height: | Size: 7.0 KiB |
|
After Width: | Height: | Size: 5.4 KiB |
|
After Width: | Height: | Size: 7.9 KiB |
|
After Width: | Height: | Size: 5.0 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 9.0 KiB After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 6.3 KiB |
|
After Width: | Height: | Size: 6.7 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 8.5 KiB After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 9.4 KiB |
|
After Width: | Height: | Size: 9.5 KiB |
|
After Width: | Height: | Size: 738 B |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 695 B |