Skip to content
Open
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
88ab62d
feat: 添加 Linux/macOS 跨平台支持
taotieren Jun 23, 2026
ed8c663
feat: 跨平台基础设施 — Core共享库 + Avalonia UI框架 + CI/构建修复
taotieren Jun 23, 2026
0833d1f
feat: 跨平台 Lua 运行时 (MoonSharp) + 编码转换/在线脚本页面迁移
taotieren Jun 23, 2026
af189d5
feat(ui): 对标 WPF 原版重构全部 UI 页面 (MainWindow/DataShow/LuaEditor/SettingW…
taotieren Jun 23, 2026
a6e82ba
feat(ui): 跨平台适配 — 字体/暗色模式/WPF 功能同步 (QuickSend 导入导出/绘图等)
taotieren Jun 23, 2026
b162063
feat(i18n): 语言切换与完整中英国际化 (LocaleHelper + 60+ DynamicResource keys)
taotieren Jun 23, 2026
6d3c293
feat(usb): WinUSB 跨平台 I/O 实现
taotieren Jun 23, 2026
a6d7f44
feat(serial): 串口监听页面
taotieren Jun 23, 2026
d77ee40
fix(i18n): 收尾硬编码字符串 + 新增页面多语言 + 重复 key 修复
taotieren Jun 23, 2026
7805276
fix(about): 补全关于页面内容对标 WPF 原版 + Linux串口监听评估 + 缺失 key 修复
taotieren Jun 23, 2026
6f54431
fix: 修复 PR #221 中 gemini-code-assist bot 指出的 8 个问题
taotieren Jun 24, 2026
3148650
feat(ui): 对标 WPF 补全 MainWindow 功能和语言文件
taotieren Jun 24, 2026
e38eff2
feat: 补全 WPF 关键功能迁移和安全修复
taotieren Jun 24, 2026
27e7fe5
feat: Terminal模式迁移、SettingWindow连接、QuickSend脚本图标 + 全面安全修复
taotieren Jun 24, 2026
4a50b4e
feat: Terminal模式迁移、SettingWindow连接、QuickSend脚本图标 + 全面安全修复
taotieren Jun 24, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
142 changes: 142 additions & 0 deletions .github/workflows/build-cross-platform.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
name: Build Cross-Platform (Avalonia)

on:
push:
branches: [ master, main, update-linux ]
pull_request:
branches: [ master, main ]
workflow_dispatch:

jobs:
# ── Build Rust native library ────────────────────────────────
build-rust:
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
runs-on: ${{ matrix.os }}

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Install Rust
uses: dtolnay/rust-toolchain@master
with:
toolchain: nightly

- name: Build serial_monitor (unix)
if: runner.os != 'Windows'
run: |
cd serial_monitor_rs
cargo build --release -p serial_monitor

- name: Build serial_monitor (windows)
if: runner.os == 'Windows'
run: |
cd serial_monitor_rs
cargo build --release -p serial_monitor_hook --target x86_64-pc-windows-msvc
cargo build --release -p serial_monitor --target x86_64-pc-windows-msvc

- name: Copy native lib (Linux)
if: runner.os == 'Linux'
run: |
mkdir -p llcom/native/linux-x64
cp serial_monitor_rs/target/release/libserial_monitor.so llcom/native/linux-x64/

- name: Copy native lib (macOS)
if: runner.os == 'macOS'
run: |
mkdir -p llcom/native/osx-x64
cp serial_monitor_rs/target/release/libserial_monitor.dylib llcom/native/osx-x64/

- name: Copy native lib (Windows)
if: runner.os == 'Windows'
run: |
New-Item -ItemType Directory -Force -Path llcom\native\win-x64
Copy-Item serial_monitor_rs\target\x86_64-pc-windows-msvc\release\serial_monitor.dll llcom\native\win-x64\

- name: Upload Rust artifacts
uses: actions/upload-artifact@v4
with:
name: native-${{ matrix.os }}
path: |
llcom/native/**

# ── Build .NET Avalonia app ──────────────────────────────────
build-dotnet:
needs: build-rust
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
rid: [linux-x64, win-x64, osx-x64]
exclude:
- os: ubuntu-latest
rid: win-x64
- os: ubuntu-latest
rid: osx-x64
- os: windows-latest
rid: linux-x64
- os: windows-latest
rid: osx-x64
- os: macos-latest
rid: linux-x64
- os: macos-latest
rid: win-x64
runs-on: ${{ matrix.os }}

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: 8.0.x

- name: Download native lib
uses: actions/download-artifact@v4
with:
name: native-${{ matrix.os }}
path: llcom/native/

- name: Restore
run: dotnet restore llcom.Avalonia/llcom.Avalonia.csproj

- name: Build
run: dotnet build llcom.Avalonia/llcom.Avalonia.csproj -c Release --no-restore

- name: Publish
run: dotnet publish llcom.Avalonia/llcom.Avalonia.csproj -c Release -r ${{ matrix.rid }} --self-contained true -p:PublishSingleFile=true -p:IncludeNativeLibrariesForSelfExtract=true -o publish/${{ matrix.rid }}

- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
name: llcom-${{ matrix.rid }}
path: publish/${{ matrix.rid }}/

# ── Build original WPF app (Windows only) ────────────────────
build-wpf:
runs-on: windows-latest
if: github.ref == 'refs/heads/master' || github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/')

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup MSBuild
uses: microsoft/setup-msbuild@v2

- name: Setup NuGet
uses: NuGet/setup-nuget@v2

- name: Restore NuGet packages
run: nuget restore llcom.sln

- name: Build
run: msbuild llcom/llcom.csproj /p:Configuration=Release /p:Platform=x64 /v:normal

- name: Upload WPF artifacts
uses: actions/upload-artifact@v4
with:
name: llcom-wpf-x64
path: llcom/bin/x64/Release/
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -333,3 +333,9 @@ ASALocalRun/
serial_monitor_rs/target/
serial_monitor_rs/Cargo.lock
**/*.rs.bk

# CodeBuddy
.codebuddy/

# Solution filter files
*.slnx
25 changes: 25 additions & 0 deletions llcom-cross.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "llcom.Core", "llcom.Core\llcom.Core.csproj", "{A1B2C3D4-E5F6-7890-ABCD-EF1234567890}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "llcom.Avalonia", "llcom.Avalonia\llcom.Avalonia.csproj", "{B2C3D4E5-F6A7-8901-BCDE-F12345678901}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{A1B2C3D4-E5F6-7890-ABCD-EF1234567890}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A1B2C3D4-E5F6-7890-ABCD-EF1234567890}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A1B2C3D4-E5F6-7890-ABCD-EF1234567890}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A1B2C3D4-E5F6-7890-ABCD-EF1234567890}.Release|Any CPU.Build.0 = Release|Any CPU
{B2C3D4E5-F6A7-8901-BCDE-F12345678901}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B2C3D4E5-F6A7-8901-BCDE-F12345678901}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B2C3D4E5-F6A7-8901-BCDE-F12345678901}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B2C3D4E5-F6A7-8901-BCDE-F12345678901}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
22 changes: 22 additions & 0 deletions llcom.Avalonia/App.axaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<Application xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="llcom.Avalonia.App"
xmlns:local="using:llcom.Avalonia"
RequestedThemeVariant="Default">
<!-- "Default" follows system theme variant (light/dark). -->

<Application.DataTemplates>
<local:ViewLocator/>
</Application.DataTemplates>

<Application.Styles>
<FluentTheme DensityStyle="Compact" />
<Style Selector="TextBlock">
<Setter Property="FontFamily" Value="Microsoft YaHei,SimHei,WenQuanYi Micro Hei,Noto Sans CJK SC,sans-serif"/>
</Style>
<Style Selector="TextBox">
<Setter Property="FontFamily" Value="Microsoft YaHei,SimHei,WenQuanYi Micro Hei,Noto Sans CJK SC,sans-serif"/>
</Style>
<!-- 等宽字体控件(TextEditor, ListBox 数据区等)不做覆盖,由各自控件指定 -->
</Application.Styles>
</Application>
64 changes: 64 additions & 0 deletions llcom.Avalonia/App.axaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
using System;
using System.Threading.Tasks;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Markup.Xaml;
using Avalonia.Markup.Xaml.Styling;
using llcom.Avalonia.ViewModels;
using llcom.Avalonia.Views;
using llcom.Tools;

namespace llcom.Avalonia;

public partial class App : Application
{
public override void Initialize()
{
AvaloniaXamlLoader.Load(this);
}

public override void OnFrameworkInitializationCompleted()
{
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{
// Initialize cross-platform abstractions
PlatformHelper.ShowMessageCallback = (msg) =>
{
Console.WriteLine($"[llcom message] {msg}");
};

// Set clipboard callback for EncodingFixViewModel
EncodingFixViewModel.CopyToClipboardCallback = async (text) =>
{
if (desktop.MainWindow is { } window)
{
var clipboard = TopLevel.GetTopLevel(window)?.Clipboard;
if (clipboard != null)
await clipboard.SetTextAsync(text);
}
};

desktop.MainWindow = new MainWindow
{
DataContext = new MainWindowViewModel(),
};

// Language switching: swap the merged ResourceDictionary at runtime
PlatformHelper.LoadLanguageFileCallback = (language) =>
{
if (desktop.MainWindow is MainWindow mainWindow)
{
var dict = mainWindow.Resources;
dict.MergedDictionaries.Clear();
dict.MergedDictionaries.Add(new ResourceInclude(default(Uri))
{
Source = new Uri($"avares://llcom/languages/{language}.xaml")
});
}
};
}

base.OnFrameworkInitializationCompleted();
}
}
Binary file added llcom.Avalonia/Assets/avalonia-logo.ico
Binary file not shown.
Binary file added llcom.Avalonia/Assets/llcom.ico
Binary file not shown.
Loading