fully functional editor

This commit is contained in:
EugeneTes
2026-02-04 14:59:16 +01:00
parent 8cd04155db
commit 1fcaaa040b
6 changed files with 151 additions and 13 deletions

View File

@@ -7,6 +7,8 @@ public class TM_T30IIITranslated : IPrinter
{
private readonly IEpsonPrinter _printer;
public bool SkipDelays { get; set; }
public TM_T30IIITranslated(IEpsonPrinter printer)
{
_printer = printer;
@@ -22,7 +24,7 @@ public class TM_T30IIITranslated : IPrinter
await _printer.FeedLinesAsync(1);
await _printer.SetAbsolutePrintPosition(100);
await _printer.LoadImageAsync(path, 384);
await Task.Delay(100);
if (!SkipDelays) await Task.Delay(100);
if (_printer is HtmlPrinter)
{
await _printer.PrintLoadedImage();
@@ -65,12 +67,12 @@ public class TM_T30IIITranslated : IPrinter
await _printer.SetDefaultLineSpacing();
await _printer.FeedLinesAsync(10);
await Task.Delay(200);
if (!SkipDelays) await Task.Delay(200);
}
public async Task Cut()
{
await _printer.CutAsync();
await Task.Delay(200);
if (!SkipDelays) await Task.Delay(200);
}
}

View File

@@ -8,6 +8,8 @@ public class TM_U220IITranslated : IPrinter
{
private readonly IEpsonPrinter _printer;
public bool SkipDelays { get; set; }
public TM_U220IITranslated(IEpsonPrinter printer)
{
_printer = printer;
@@ -16,7 +18,7 @@ public class TM_U220IITranslated : IPrinter
public async Task InitAsync()
{
await _printer.InitAsync();
await Task.Delay(200);
if (!SkipDelays) await Task.Delay(200);
}
public Task PrintImageAsync(string path)
@@ -39,28 +41,28 @@ public class TM_U220IITranslated : IPrinter
if (command.IsCut)
{
await _printer.FeedLinesAsync(10);
await Task.Delay(200 * 5);
if (!SkipDelays) await Task.Delay(200 * 5);
await _printer.CutAsync(false);
await Task.Delay(200);
if (!SkipDelays) await Task.Delay(200);
continue;
}
await _printer.SetBiggerFontTM220(command.IsBig, command.IsTall | command.IsBig);
await Task.Delay(200);
if (!SkipDelays) await Task.Delay(200);
await _printer.SetRedColor(command.IsRed);
await Task.Delay(200);
if (!SkipDelays) await Task.Delay(200);
await _printer.SetEmphasized(command.IsBold);
await Task.Delay(200);
if (!SkipDelays) await Task.Delay(200);
await _printer.PrintTextAsync(command.Text + "\n");
await Task.Delay(200);
if (!SkipDelays) await Task.Delay(200);
}
await _printer.FeedLinesAsync(10);
await Task.Delay(1000);
if (!SkipDelays) await Task.Delay(1000);
}
public async Task Cut()
{
await _printer.CutAsync();
await Task.Delay(200);
if (!SkipDelays) await Task.Delay(200);
}
}

View File

@@ -3,6 +3,9 @@
@using BlazorMonaco.Editor
@using BlazorMonaco.Languages
@using CommunityToolkit.Maui.Storage
@using Inspectron.Epson
@using Inspectron.Epson.PrintServer.Printers
@using Inspectron.Epson.TemplateEngine
@using Inspectron.PrintServer.TemplateEditor.Services
@inject IJSRuntime JSRuntime
@@ -20,6 +23,11 @@
{
<span class="json-indicator" title="@_loadedJsonFile">@_loadedJsonFile</span>
}
<div class="toolbar-separator"></div>
<select class="toolbar-select" title="Printer model" @onchange="OnPrinterModelChanged" value="@_selectedPrinterModel">
<option value="TM-T30III">TM-T30III</option>
<option value="TM-U220II">TM-U220II</option>
</select>
</div>
<div class="split-pane">
@@ -34,6 +42,11 @@
<div class="pane pane-preview">
<div class="pane-header">Preview</div>
<div class="preview-content">
@if (!string.IsNullOrEmpty(_previewError))
{
<div class="preview-error">@_previewError</div>
}
<iframe id="preview-iframe"></iframe>
</div>
</div>
</div>
@@ -48,6 +61,12 @@
private string? _currentFilePath;
private string _savedContent = "";
private string? _jsonContent;
private string? _previewHtml;
private string? _previewError;
private string _selectedPrinterModel = "TM-T30III";
private CancellationTokenSource? _debounceCts;
private bool HasUnsavedChanges => _editorContent != _savedContent;
private string FileDisplayName => _currentFilePath is not null
@@ -87,6 +106,24 @@
private async Task OnContentChanged(ModelContentChangedEvent e)
{
_editorContent = await _editor.GetValue();
_debounceCts?.Cancel();
_debounceCts = new CancellationTokenSource();
var token = _debounceCts.Token;
_ = Task.Run(async () =>
{
try
{
await Task.Delay(500, token);
await InvokeAsync(async () =>
{
await RenderPreviewAsync();
StateHasChanged();
});
}
catch (TaskCanceledException) { }
});
}
private async Task NewFileAsync()
@@ -95,6 +132,9 @@
_savedContent = "";
_editorContent = "";
await _editor.SetValue("");
_previewHtml = null;
_previewError = null;
await JSRuntime.InvokeVoidAsync("setPreviewContent", "");
}
private async Task OpenFileAsync()
@@ -121,6 +161,7 @@
_savedContent = content;
_editorContent = content;
await _editor.SetValue(content);
await RenderPreviewAsync();
}
catch (Exception)
{
@@ -183,10 +224,13 @@
using var reader = new StreamReader(stream);
var json = await reader.ReadToEndAsync();
_jsonContent = json;
var paths = JsonPathExtractor.Extract(json);
_completionProvider.SetJsonPaths(paths);
_loadedJsonFile = result.FileName;
await RenderPreviewAsync();
StateHasChanged();
}
catch (Exception)
@@ -194,4 +238,51 @@
// User cancelled or file read failed
}
}
private async Task OnPrinterModelChanged(ChangeEventArgs e)
{
_selectedPrinterModel = e.Value?.ToString() ?? "TM-T30III";
await RenderPreviewAsync();
}
private async Task RenderPreviewAsync()
{
if (string.IsNullOrWhiteSpace(_editorContent) || string.IsNullOrWhiteSpace(_jsonContent))
return;
try
{
_previewError = null;
var engine = new ReceiptTemplateEngine();
var commands = engine.Render(_editorContent, _jsonContent);
var htmlBuilder = new HtmlPrintBuilder();
await htmlBuilder.ConnectAsync("preview");
if (_selectedPrinterModel == "TM-U220II")
{
var printer = new TM_U220IITranslated(htmlBuilder) { SkipDelays = true };
await printer.InitAsync();
await printer.PrintAsync(commands);
await printer.Cut();
}
else
{
var printer = new TM_T30IIITranslated(htmlBuilder) { SkipDelays = true };
await printer.InitAsync();
await printer.PrintAsync(commands);
await printer.Cut();
}
_previewHtml = htmlBuilder.GetHtml();
await JSRuntime.InvokeVoidAsync("setPreviewContent", _previewHtml);
}
catch (Exception ex)
{
_previewError = ex.Message;
_previewHtml = null;
await JSRuntime.InvokeVoidAsync("setPreviewContent", "");
}
}
}

View File

@@ -53,6 +53,11 @@
<MauiAsset Include="Resources\Raw\**" LogicalName="%(RecursiveDir)%(Filename)%(Extension)" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Inspectron.Epson\Inspectron.Epson.csproj" />
<ProjectReference Include="..\Inspectron.Epson.TemplateEngine\Inspectron.Epson.TemplateEngine.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="BlazorMonaco" Version="3.4.0" />
<PackageReference Include="CommunityToolkit.Maui" Version="13.0.0" />

View File

@@ -111,9 +111,42 @@ html, body {
.preview-content {
flex: 1;
padding: 16px;
padding: 0;
overflow: auto;
color: #cccccc;
display: flex;
flex-direction: column;
}
#preview-iframe {
flex: 1;
width: 100%;
border: none;
background: #f0f0f0;
}
.preview-error {
padding: 8px 12px;
color: #f44747;
background: #2a1515;
border-bottom: 1px solid #5a2020;
font-size: 12px;
font-family: 'Courier New', monospace;
white-space: pre-wrap;
}
.toolbar-select {
padding: 4px 8px;
background: #3c3c3c;
color: #cccccc;
border: 1px solid #555;
border-radius: 3px;
cursor: pointer;
font-size: 13px;
}
.toolbar-select:hover {
background: #505050;
}
.valid.modified:not([type=checkbox]) {
outline: 1px solid #26b050;

View File

@@ -156,3 +156,8 @@ window.receiptLanguage = {
return '';
}
};
window.setPreviewContent = function(html) {
var iframe = document.getElementById('preview-iframe');
if (iframe) iframe.srcdoc = html;
};