From 36f8ebfebe553d07e8af7d63b61940af3457c5a9 Mon Sep 17 00:00:00 2001 From: NinjaPug <36635276+programmingPug@users.noreply.github.com> Date: Thu, 15 May 2025 10:56:45 -0400 Subject: [PATCH] defect updates, bug still in code --- PCPal/Configurator/AppShell.xaml.cs | 1 - .../Controls/OledDisplayCanvas.cs | 242 +++++++ .../Controls/OledPreviewCanvas.cs | 383 +--------- PCPal/Configurator/MauiProgram.cs | 1 - .../ViewModels/OledConfigViewModel.cs | 653 +----------------- .../Views/OLED/OledConfigView.xaml | 16 +- .../Views/OLED/OledMarkupEditorView.xaml | 13 +- .../Views/OLED/OledTemplatesView.xaml | 9 +- 8 files changed, 282 insertions(+), 1036 deletions(-) create mode 100644 PCPal/Configurator/Controls/OledDisplayCanvas.cs diff --git a/PCPal/Configurator/AppShell.xaml.cs b/PCPal/Configurator/AppShell.xaml.cs index 653e982..980a407 100644 --- a/PCPal/Configurator/AppShell.xaml.cs +++ b/PCPal/Configurator/AppShell.xaml.cs @@ -5,7 +5,6 @@ using PCPal.Configurator.Views.LCD; using PCPal.Configurator.Views.OLED; using PCPal.Configurator.Views.TFT; using System.ComponentModel; -using PCPal.Configurator.Models; using System.Collections.ObjectModel; namespace PCPal.Configurator; diff --git a/PCPal/Configurator/Controls/OledDisplayCanvas.cs b/PCPal/Configurator/Controls/OledDisplayCanvas.cs new file mode 100644 index 0000000..821f4f9 --- /dev/null +++ b/PCPal/Configurator/Controls/OledDisplayCanvas.cs @@ -0,0 +1,242 @@ +using Microsoft.Maui.Controls.Shapes; +using PCPal.Core.Models; +using System.Collections.ObjectModel; +using System.Collections.Specialized; + +namespace PCPal.Configurator.Controls; + +// This is a new control that only handles display functionality - no editing +public class OledDisplayCanvas : GraphicsView +{ + // Bindable properties for the control + public static readonly BindableProperty ElementsProperty = BindableProperty.Create( + nameof(Elements), + typeof(IList), + typeof(OledDisplayCanvas), + null, + propertyChanged: OnElementsChanged); + + public static readonly BindableProperty ScaleProperty = BindableProperty.Create( + nameof(Scale), + typeof(float), + typeof(OledDisplayCanvas), + 1.0f, + propertyChanged: OnScaleChanged); + + public static readonly BindableProperty CanvasWidthProperty = BindableProperty.Create( + nameof(CanvasWidth), + typeof(int), + typeof(OledDisplayCanvas), + 256); + + public static readonly BindableProperty CanvasHeightProperty = BindableProperty.Create( + nameof(CanvasHeight), + typeof(int), + typeof(OledDisplayCanvas), + 64); + + // Property accessors + public IList Elements + { + get => (IList)GetValue(ElementsProperty); + set => SetValue(ElementsProperty, value); + } + + public float Scale + { + get => (float)GetValue(ScaleProperty); + set => SetValue(ScaleProperty, value); + } + + public int CanvasWidth + { + get => (int)GetValue(CanvasWidthProperty); + set => SetValue(CanvasWidthProperty, value); + } + + public int CanvasHeight + { + get => (int)GetValue(CanvasHeightProperty); + set => SetValue(CanvasHeightProperty, value); + } + + // Constructor + public OledDisplayCanvas() + { + // Set default drawing + Drawable = new OledDisplayDrawable(this); + + // Set up initial size + WidthRequest = 256 * Scale; + HeightRequest = 64 * Scale; + } + + // Element collection change handler + private static void OnElementsChanged(BindableObject bindable, object oldValue, object newValue) + { + var canvas = (OledDisplayCanvas)bindable; + + // If old value is INotifyCollectionChanged, unsubscribe + if (oldValue is INotifyCollectionChanged oldCollection) + { + oldCollection.CollectionChanged -= canvas.OnCollectionChanged; + } + + // If new value is INotifyCollectionChanged, subscribe + if (newValue is INotifyCollectionChanged newCollection) + { + newCollection.CollectionChanged += canvas.OnCollectionChanged; + } + + // Invalidate the canvas to redraw + canvas.Invalidate(); + } + + // Scale change handler + private static void OnScaleChanged(BindableObject bindable, object oldValue, object newValue) + { + var canvas = (OledDisplayCanvas)bindable; + float scale = (float)newValue; + + // Update the size of the canvas based on the scale + canvas.WidthRequest = canvas.CanvasWidth * scale; + canvas.HeightRequest = canvas.CanvasHeight * scale; + + canvas.Invalidate(); + } + + // Collection changed event handler + private void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) + { + Invalidate(); + } +} + +// The drawable that renders the OLED canvas +public class OledDisplayDrawable : IDrawable +{ + private readonly OledDisplayCanvas _canvas; + + public OledDisplayDrawable(OledDisplayCanvas canvas) + { + _canvas = canvas; + } + + public void Draw(ICanvas canvas, RectF dirtyRect) + { + try + { + float scale = _canvas.Scale; + + // Clear background + canvas.FillColor = Colors.Black; + canvas.FillRectangle(0, 0, dirtyRect.Width, dirtyRect.Height); + + // Draw elements + if (_canvas.Elements != null) + { + foreach (var element in _canvas.Elements) + { + DrawElement(canvas, element, scale); + } + } + } + catch (Exception ex) + { + System.Diagnostics.Debug.WriteLine($"Error drawing canvas: {ex.Message}"); + } + } + + private void DrawElement(ICanvas canvas, PreviewElement element, float scale) + { + canvas.StrokeColor = Colors.White; + canvas.StrokeSize = 1; + canvas.FillColor = Colors.White; + + if (element is TextElement textElement) + { + float fontSize; + switch (textElement.Size) + { + case 1: fontSize = 8 * scale; break; + case 2: fontSize = 12 * scale; break; + case 3: fontSize = 16 * scale; break; + default: fontSize = 8 * scale; break; + } + + canvas.FontSize = fontSize; + canvas.FontColor = Colors.White; + canvas.DrawString( + textElement.Text, + textElement.X * scale, + textElement.Y * scale, + HorizontalAlignment.Left); + } + else if (element is BarElement barElement) + { + // Draw outline + canvas.DrawRectangle( + barElement.X * scale, + barElement.Y * scale, + barElement.Width * scale, + barElement.Height * scale); + + // Draw fill based on value + int fillWidth = (int)(barElement.Width * (barElement.Value / 100.0)); + if (fillWidth > 0) + { + canvas.FillRectangle( + (barElement.X + 1) * scale, + (barElement.Y + 1) * scale, + (fillWidth - 1) * scale, + (barElement.Height - 2) * scale); + } + } + else if (element is RectElement rectElement) + { + if (rectElement.Filled) + { + // Filled box + canvas.FillRectangle( + rectElement.X * scale, + rectElement.Y * scale, + rectElement.Width * scale, + rectElement.Height * scale); + } + else + { + // Outline rectangle + canvas.DrawRectangle( + rectElement.X * scale, + rectElement.Y * scale, + rectElement.Width * scale, + rectElement.Height * scale); + } + } + else if (element is LineElement lineElement) + { + canvas.DrawLine( + lineElement.X1 * scale, + lineElement.Y1 * scale, + lineElement.X2 * scale, + lineElement.Y2 * scale); + } + else if (element is IconElement iconElement) + { + // Draw a placeholder for the icon + canvas.DrawRectangle( + iconElement.X * scale, + iconElement.Y * scale, + 24 * scale, + 24 * scale); + + // Draw icon name as text + canvas.FontSize = 8 * scale; + canvas.DrawString( + iconElement.Name, + (iconElement.X + 2) * scale, + (iconElement.Y + 12) * scale, + HorizontalAlignment.Left); + } + } +} \ No newline at end of file diff --git a/PCPal/Configurator/Controls/OledPreviewCanvas.cs b/PCPal/Configurator/Controls/OledPreviewCanvas.cs index 3de217b..5d82089 100644 --- a/PCPal/Configurator/Controls/OledPreviewCanvas.cs +++ b/PCPal/Configurator/Controls/OledPreviewCanvas.cs @@ -1,5 +1,4 @@ using Microsoft.Maui.Controls.Shapes; -using PCPal.Configurator.ViewModels; using PCPal.Core.Models; using System.Collections.ObjectModel; using System.Collections.Specialized; @@ -16,20 +15,6 @@ public class OledPreviewCanvas : GraphicsView null, propertyChanged: OnElementsChanged); - public static readonly BindableProperty SelectedElementProperty = BindableProperty.Create( - nameof(SelectedElement), - typeof(OledElement), - typeof(OledPreviewCanvas), - null, - BindingMode.TwoWay, - propertyChanged: OnSelectedElementChanged); - - public static readonly BindableProperty IsEditableProperty = BindableProperty.Create( - nameof(IsEditable), - typeof(bool), - typeof(OledPreviewCanvas), - false); - public static readonly BindableProperty ScaleProperty = BindableProperty.Create( nameof(Scale), typeof(float), @@ -56,18 +41,6 @@ public class OledPreviewCanvas : GraphicsView set => SetValue(ElementsProperty, value); } - public OledElement SelectedElement - { - get => (OledElement)GetValue(SelectedElementProperty); - set => SetValue(SelectedElementProperty, value); - } - - public bool IsEditable - { - get => (bool)GetValue(IsEditableProperty); - set => SetValue(IsEditableProperty, value); - } - public float Scale { get => (float)GetValue(ScaleProperty); @@ -92,11 +65,6 @@ public class OledPreviewCanvas : GraphicsView // Set default drawing Drawable = new OledCanvasDrawable(this); - // Set up interaction handlers if editable - StartInteraction += OnStartInteraction; - DragInteraction += OnDragInteraction; - EndInteraction += OnEndInteraction; - // Set up initial size WidthRequest = 256 * Scale; HeightRequest = 64 * Scale; @@ -123,13 +91,6 @@ public class OledPreviewCanvas : GraphicsView canvas.Invalidate(); } - // Selected element change handler - private static void OnSelectedElementChanged(BindableObject bindable, object oldValue, object newValue) - { - var canvas = (OledPreviewCanvas)bindable; - canvas.Invalidate(); - } - // Scale change handler private static void OnScaleChanged(BindableObject bindable, object oldValue, object newValue) { @@ -148,225 +109,6 @@ public class OledPreviewCanvas : GraphicsView { Invalidate(); } - - // Interaction handlers for element selection and manipulation - private OledElement draggedElement; - private Point dragStartPoint; - - private void OnStartInteraction(object sender, TouchEventArgs e) - { - if (!IsEditable) return; - - var point = e.Touches[0]; - dragStartPoint = point; - - // Check if an element was clicked - if (Elements == null || Elements.Count == 0) return; - - // Need to adjust for scale - float x = (float)point.X / Scale; - float y = (float)point.Y / Scale; - - // Check in reverse order (top elements first) - for (int i = Elements.Count - 1; i >= 0; i--) - { - var element = Elements[i]; - - if (element is TextElement textElement) - { - // Simple bounding box check - if (x >= textElement.X && x <= textElement.X + 100 && - y >= textElement.Y - 20 && y <= textElement.Y) - { - // Find the OledElement that corresponds to this PreviewElement - var oledElement = FindOledElementForPreviewElement(textElement); - if (oledElement != null) - { - draggedElement = oledElement; - SelectedElement = oledElement; - return; - } - } - } - else if (element is BarElement barElement) - { - if (x >= barElement.X && x <= barElement.X + barElement.Width && - y >= barElement.Y && y <= barElement.Y + barElement.Height) - { - var oledElement = FindOledElementForPreviewElement(barElement); - if (oledElement != null) - { - draggedElement = oledElement; - SelectedElement = oledElement; - return; - } - } - } - else if (element is RectElement rectElement) - { - if (x >= rectElement.X && x <= rectElement.X + rectElement.Width && - y >= rectElement.Y && y <= rectElement.Y + rectElement.Height) - { - var oledElement = FindOledElementForPreviewElement(rectElement); - if (oledElement != null) - { - draggedElement = oledElement; - SelectedElement = oledElement; - return; - } - } - } - else if (element is LineElement lineElement) - { - // Simplified line hit detection - float distance = DistancePointToLine( - x, y, - lineElement.X1, lineElement.Y1, - lineElement.X2, lineElement.Y2); - - if (distance < 10) // 10 pixel tolerance - { - var oledElement = FindOledElementForPreviewElement(lineElement); - if (oledElement != null) - { - draggedElement = oledElement; - SelectedElement = oledElement; - return; - } - } - } - else if (element is IconElement iconElement) - { - if (x >= iconElement.X && x <= iconElement.X + 24 && - y >= iconElement.Y && y <= iconElement.Y + 24) - { - var oledElement = FindOledElementForPreviewElement(iconElement); - if (oledElement != null) - { - draggedElement = oledElement; - SelectedElement = oledElement; - return; - } - } - } - } - - // No element was clicked, deselect - SelectedElement = null; - } - - private void OnDragInteraction(object sender, TouchEventArgs e) - { - if (!IsEditable || draggedElement == null) return; - - try - { - var point = e.Touches[0]; - - // Calculate the delta from the start point - float deltaX = (float)(point.X - dragStartPoint.X) / Scale; - float deltaY = (float)(point.Y - dragStartPoint.Y) / Scale; - - // Update the position of the dragged element - draggedElement.X += (int)deltaX; - draggedElement.Y += (int)deltaY; - - // Keep element within bounds - draggedElement.X = Math.Max(0, Math.Min(Width - 10, draggedElement.X)); - draggedElement.Y = Math.Max(0, Math.Min(Height - 10, draggedElement.Y)); - - // Update the start point for the next move - dragStartPoint = point; - - // Notify property changes - var viewModel = BindingContext as PCPal.Configurator.ViewModels.OledConfigViewModel; - if (viewModel != null) - { - // Update the view model properties to reflect the new position - viewModel.OnPropertyChanged(nameof(viewModel.SelectedElementX)); - viewModel.OnPropertyChanged(nameof(viewModel.SelectedElementY)); - - // Update the markup - viewModel.UpdateMarkupFromElements(); - } - - // Invalidate the canvas to redraw - Invalidate(); - } - catch (Exception ex) - { - System.Diagnostics.Debug.WriteLine($"Error in drag interaction: {ex.Message}"); - } - } - - private void OnEndInteraction(object sender, TouchEventArgs e) - { - draggedElement = null; - } - - // Helper methods - private OledElement FindOledElementForPreviewElement(PreviewElement previewElement) - { - var viewModel = BindingContext as OledConfigViewModel; - if (viewModel == null || viewModel.OledElements == null) return null; - - foreach (var oledElement in viewModel.OledElements) - { - // Match based on position and type - if (previewElement is TextElement textElement && oledElement.Type == "text") - { - if (oledElement.X == textElement.X && oledElement.Y == textElement.Y) - { - return oledElement; - } - } - else if (previewElement is BarElement barElement && oledElement.Type == "bar") - { - if (oledElement.X == barElement.X && oledElement.Y == barElement.Y) - { - return oledElement; - } - } - else if (previewElement is RectElement rectElement) - { - if ((oledElement.Type == "rect" || oledElement.Type == "box") && - oledElement.X == rectElement.X && oledElement.Y == rectElement.Y) - { - return oledElement; - } - } - else if (previewElement is LineElement lineElement && oledElement.Type == "line") - { - if (oledElement.X == lineElement.X1 && oledElement.Y == lineElement.Y1) - { - return oledElement; - } - } - else if (previewElement is IconElement iconElement && oledElement.Type == "icon") - { - if (oledElement.X == iconElement.X && oledElement.Y == iconElement.Y) - { - return oledElement; - } - } - } - - return null; - } - - private float DistancePointToLine(float px, float py, float x1, float y1, float x2, float y2) - { - float lineLength = (float)Math.Sqrt(Math.Pow(x2 - x1, 2) + Math.Pow(y2 - y1, 2)); - if (lineLength == 0) return (float)Math.Sqrt(Math.Pow(px - x1, 2) + Math.Pow(py - y1, 2)); - - float t = ((px - x1) * (x2 - x1) + (py - y1) * (y2 - y1)) / (lineLength * lineLength); - t = Math.Max(0, Math.Min(1, t)); - - float projX = x1 + t * (x2 - x1); - float projY = y1 + t * (y2 - y1); - - return (float)Math.Sqrt(Math.Pow(px - projX, 2) + Math.Pow(py - projY, 2)); - } } // The drawable that renders the OLED canvas @@ -389,59 +131,12 @@ public class OledCanvasDrawable : IDrawable canvas.FillColor = Colors.Black; canvas.FillRectangle(0, 0, dirtyRect.Width, dirtyRect.Height); - // Draw grid if requested - if (_canvas.IsEditable && _canvas.Parent?.BindingContext is OledConfigViewModel viewModel && viewModel.ShowGridLines) - { - canvas.StrokeColor = new Color(64, 64, 64, 64); // Semi-transparent gray - canvas.StrokeSize = 1; - - // Draw vertical grid lines - for (int x = 0; x <= _canvas.Width; x += 10) - { - canvas.DrawLine(x * scale, 0, x * scale, _canvas.Height * scale); - } - - // Draw horizontal grid lines - for (int y = 0; y <= _canvas.Height; y += 10) - { - canvas.DrawLine(0, y * scale, _canvas.Width * scale, y * scale); - } - } - // Draw elements if (_canvas.Elements != null) { foreach (var element in _canvas.Elements) { - // Check if this element is selected - bool isSelected = false; - if (_canvas.SelectedElement != null && _canvas.IsEditable) - { - if (element is TextElement textElement && _canvas.SelectedElement.Type == "text") - { - isSelected = _canvas.SelectedElement.X == textElement.X && _canvas.SelectedElement.Y == textElement.Y; - } - else if (element is BarElement barElement && _canvas.SelectedElement.Type == "bar") - { - isSelected = _canvas.SelectedElement.X == barElement.X && _canvas.SelectedElement.Y == barElement.Y; - } - else if (element is RectElement rectElement && - (_canvas.SelectedElement.Type == "rect" || _canvas.SelectedElement.Type == "box")) - { - isSelected = _canvas.SelectedElement.X == rectElement.X && _canvas.SelectedElement.Y == rectElement.Y; - } - else if (element is LineElement lineElement && _canvas.SelectedElement.Type == "line") - { - isSelected = _canvas.SelectedElement.X == lineElement.X1 && _canvas.SelectedElement.Y == lineElement.Y1; - } - else if (element is IconElement iconElement && _canvas.SelectedElement.Type == "icon") - { - isSelected = _canvas.SelectedElement.X == iconElement.X && _canvas.SelectedElement.Y == iconElement.Y; - } - } - - // Draw the element with appropriate styling - DrawElement(canvas, element, scale, isSelected); + DrawElement(canvas, element, scale); } } } @@ -451,20 +146,10 @@ public class OledCanvasDrawable : IDrawable } } - private void DrawElement(ICanvas canvas, PreviewElement element, float scale, bool isSelected) + private void DrawElement(ICanvas canvas, PreviewElement element, float scale) { - // Set selection highlighting if needed - if (isSelected) - { - canvas.StrokeColor = Colors.Cyan; - canvas.StrokeSize = 2; - } - else - { - canvas.StrokeColor = Colors.White; - canvas.StrokeSize = 1; - } - + canvas.StrokeColor = Colors.White; + canvas.StrokeSize = 1; canvas.FillColor = Colors.White; if (element is TextElement textElement) @@ -485,17 +170,6 @@ public class OledCanvasDrawable : IDrawable textElement.X * scale, textElement.Y * scale, HorizontalAlignment.Left); - - // Draw selection indicator for text elements - if (isSelected) - { - var metrics = canvas.GetStringSize(textElement.Text, Microsoft.Maui.Graphics.Font.Default, fontSize); - canvas.DrawRectangle( - textElement.X * scale - 2, - textElement.Y * scale - metrics.Height - 2, - metrics.Width + 4, - metrics.Height + 4); - } } else if (element is BarElement barElement) { @@ -516,17 +190,6 @@ public class OledCanvasDrawable : IDrawable (fillWidth - 1) * scale, (barElement.Height - 2) * scale); } - - // Draw selection indicator - if (isSelected) - { - canvas.StrokeColor = Colors.Cyan; - canvas.DrawRectangle( - (barElement.X - 2) * scale, - (barElement.Y - 2) * scale, - (barElement.Width + 4) * scale, - (barElement.Height + 4) * scale); - } } else if (element is RectElement rectElement) { @@ -548,17 +211,6 @@ public class OledCanvasDrawable : IDrawable rectElement.Width * scale, rectElement.Height * scale); } - - // Draw selection indicator - if (isSelected) - { - canvas.StrokeColor = Colors.Cyan; - canvas.DrawRectangle( - (rectElement.X - 2) * scale, - (rectElement.Y - 2) * scale, - (rectElement.Width + 4) * scale, - (rectElement.Height + 4) * scale); - } } else if (element is LineElement lineElement) { @@ -567,22 +219,6 @@ public class OledCanvasDrawable : IDrawable lineElement.Y1 * scale, lineElement.X2 * scale, lineElement.Y2 * scale); - - // Draw selection indicator - if (isSelected) - { - canvas.StrokeColor = Colors.Cyan; - canvas.StrokeSize = 3; - canvas.DrawLine( - lineElement.X1 * scale, - lineElement.Y1 * scale, - lineElement.X2 * scale, - lineElement.Y2 * scale); - - // Draw endpoints - canvas.FillCircle(lineElement.X1 * scale, lineElement.Y1 * scale, 4); - canvas.FillCircle(lineElement.X2 * scale, lineElement.Y2 * scale, 4); - } } else if (element is IconElement iconElement) { @@ -600,17 +236,6 @@ public class OledCanvasDrawable : IDrawable (iconElement.X + 2) * scale, (iconElement.Y + 12) * scale, HorizontalAlignment.Left); - - // Draw selection indicator - if (isSelected) - { - canvas.StrokeColor = Colors.Cyan; - canvas.DrawRectangle( - (iconElement.X - 2) * scale, - (iconElement.Y - 2) * scale, - (24 + 4) * scale, - (24 + 4) * scale); - } } } } \ No newline at end of file diff --git a/PCPal/Configurator/MauiProgram.cs b/PCPal/Configurator/MauiProgram.cs index 2944686..664020b 100644 --- a/PCPal/Configurator/MauiProgram.cs +++ b/PCPal/Configurator/MauiProgram.cs @@ -36,7 +36,6 @@ public static class MauiProgram // OLED builder.Services.AddTransient(); builder.Services.AddTransient(); - builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); diff --git a/PCPal/Configurator/ViewModels/OledConfigViewModel.cs b/PCPal/Configurator/ViewModels/OledConfigViewModel.cs index f891bf3..8a6ad83 100644 --- a/PCPal/Configurator/ViewModels/OledConfigViewModel.cs +++ b/PCPal/Configurator/ViewModels/OledConfigViewModel.cs @@ -5,7 +5,6 @@ using System.Collections.ObjectModel; using System.Windows.Input; using System.Text.RegularExpressions; using System.Diagnostics; -//using Javax.Xml.Transform; namespace PCPal.Configurator.ViewModels; @@ -16,7 +15,6 @@ public class OledConfigViewModel : BaseViewModel private readonly ISerialPortService _serialPortService; // Tab selection - private bool _isVisualEditorSelected; private bool _isMarkupEditorSelected; private bool _isTemplatesSelected; private ContentView _currentView; @@ -25,14 +23,6 @@ public class OledConfigViewModel : BaseViewModel private string _oledMarkup; private List _previewElements; - // Visual editor data - private ObservableCollection _oledElements; - private OledElement _selectedElement; - private bool _showGridLines; - private float _zoomLevel; - private string _currentSensorFilter; - private ObservableCollection _filteredSensors; - // Common properties private ObservableCollection _availableSensors; @@ -43,7 +33,6 @@ public class OledConfigViewModel : BaseViewModel private string _newTemplateName; // Views - private readonly OledVisualEditorView _visualEditorView; private readonly OledMarkupEditorView _markupEditorView; private readonly OledTemplatesView _templatesView; @@ -54,12 +43,6 @@ public class OledConfigViewModel : BaseViewModel #region Properties // Tab selection properties - public bool IsVisualEditorSelected - { - get => _isVisualEditorSelected; - set => SetProperty(ref _isVisualEditorSelected, value); - } - public bool IsMarkupEditorSelected { get => _isMarkupEditorSelected; @@ -91,80 +74,6 @@ public class OledConfigViewModel : BaseViewModel set => SetProperty(ref _previewElements, value); } - // Visual editor properties - public ObservableCollection OledElements - { - get => _oledElements; - set => SetProperty(ref _oledElements, value); - } - - public OledElement SelectedElement - { - get => _selectedElement; - set - { - if (SetProperty(ref _selectedElement, value)) - { - OnPropertyChanged(nameof(HasSelectedElement)); - OnPropertyChanged(nameof(IsTextElementSelected)); - OnPropertyChanged(nameof(IsBarElementSelected)); - OnPropertyChanged(nameof(IsRectangleElementSelected)); - OnPropertyChanged(nameof(IsLineElementSelected)); - OnPropertyChanged(nameof(IsIconElementSelected)); - - // Update element properties - OnPropertyChanged(nameof(SelectedElementX)); - OnPropertyChanged(nameof(SelectedElementY)); - OnPropertyChanged(nameof(SelectedElementText)); - OnPropertyChanged(nameof(SelectedElementSize)); - OnPropertyChanged(nameof(SelectedElementWidth)); - OnPropertyChanged(nameof(SelectedElementHeight)); - OnPropertyChanged(nameof(SelectedElementValue)); - OnPropertyChanged(nameof(SelectedElementX2)); - OnPropertyChanged(nameof(SelectedElementY2)); - OnPropertyChanged(nameof(SelectedElementIconName)); - OnPropertyChanged(nameof(SelectedElementSensor)); - } - } - } - - public bool HasSelectedElement => SelectedElement != null; - public bool IsTextElementSelected => SelectedElement?.Type == "text"; - public bool IsBarElementSelected => SelectedElement?.Type == "bar"; - public bool IsRectangleElementSelected => SelectedElement?.Type == "rect" || SelectedElement?.Type == "box"; - public bool IsLineElementSelected => SelectedElement?.Type == "line"; - public bool IsIconElementSelected => SelectedElement?.Type == "icon"; - - public bool ShowGridLines - { - get => _showGridLines; - set => SetProperty(ref _showGridLines, value); - } - - public float ZoomLevel - { - get => _zoomLevel; - set => SetProperty(ref _zoomLevel, value); - } - - public string CurrentSensorFilter - { - get => _currentSensorFilter; - set - { - if (SetProperty(ref _currentSensorFilter, value)) - { - ApplySensorFilter(); - } - } - } - - public ObservableCollection FilteredSensors - { - get => _filteredSensors; - set => SetProperty(ref _filteredSensors, value); - } - // Common properties public ObservableCollection AvailableSensors { @@ -205,177 +114,11 @@ public class OledConfigViewModel : BaseViewModel set => SetProperty(ref _newTemplateName, value); } - // Selected element properties - public string SelectedElementX - { - get => SelectedElement?.X.ToString() ?? string.Empty; - set - { - if (SelectedElement != null && int.TryParse(value, out int x)) - { - SelectedElement.X = x; - UpdateMarkupFromElements(); - OnPropertyChanged(nameof(SelectedElementX)); - } - } - } - - public string SelectedElementY - { - get => SelectedElement?.Y.ToString() ?? string.Empty; - set - { - if (SelectedElement != null && int.TryParse(value, out int y)) - { - SelectedElement.Y = y; - UpdateMarkupFromElements(); - OnPropertyChanged(nameof(SelectedElementY)); - } - } - } - - public string SelectedElementText - { - get => SelectedElement?.Properties.GetValueOrDefault("content") ?? string.Empty; - set - { - if (SelectedElement != null) - { - SelectedElement.Properties["content"] = value; - UpdateMarkupFromElements(); - OnPropertyChanged(nameof(SelectedElementText)); - } - } - } - - public string SelectedElementSize - { - get => SelectedElement?.Properties.GetValueOrDefault("size") ?? "1"; - set - { - if (SelectedElement != null) - { - SelectedElement.Properties["size"] = value; - UpdateMarkupFromElements(); - OnPropertyChanged(nameof(SelectedElementSize)); - } - } - } - - public string SelectedElementWidth - { - get => SelectedElement?.Properties.GetValueOrDefault("width") ?? string.Empty; - set - { - if (SelectedElement != null && int.TryParse(value, out int width)) - { - SelectedElement.Properties["width"] = width.ToString(); - UpdateMarkupFromElements(); - OnPropertyChanged(nameof(SelectedElementWidth)); - } - } - } - - public string SelectedElementHeight - { - get => SelectedElement?.Properties.GetValueOrDefault("height") ?? string.Empty; - set - { - if (SelectedElement != null && int.TryParse(value, out int height)) - { - SelectedElement.Properties["height"] = height.ToString(); - UpdateMarkupFromElements(); - OnPropertyChanged(nameof(SelectedElementHeight)); - } - } - } - - public float SelectedElementValue - { - get - { - if (SelectedElement != null && float.TryParse(SelectedElement.Properties.GetValueOrDefault("value"), out float value)) - { - return value; - } - return 0; - } - set - { - if (SelectedElement != null) - { - SelectedElement.Properties["value"] = value.ToString("F0"); - UpdateMarkupFromElements(); - OnPropertyChanged(nameof(SelectedElementValue)); - } - } - } - - public string SelectedElementX2 - { - get => SelectedElement?.Properties.GetValueOrDefault("x2") ?? string.Empty; - set - { - if (SelectedElement != null && int.TryParse(value, out int x2)) - { - SelectedElement.Properties["x2"] = x2.ToString(); - UpdateMarkupFromElements(); - OnPropertyChanged(nameof(SelectedElementX2)); - } - } - } - - public string SelectedElementY2 - { - get => SelectedElement?.Properties.GetValueOrDefault("y2") ?? string.Empty; - set - { - if (SelectedElement != null && int.TryParse(value, out int y2)) - { - SelectedElement.Properties["y2"] = y2.ToString(); - UpdateMarkupFromElements(); - OnPropertyChanged(nameof(SelectedElementY2)); - } - } - } - - public string SelectedElementIconName - { - get => SelectedElement?.Properties.GetValueOrDefault("name") ?? string.Empty; - set - { - if (SelectedElement != null) - { - SelectedElement.Properties["name"] = value; - UpdateMarkupFromElements(); - OnPropertyChanged(nameof(SelectedElementIconName)); - } - } - } - - public string SelectedElementSensor - { - get => SelectedElement?.Properties.GetValueOrDefault("sensor") ?? string.Empty; - set - { - if (SelectedElement != null) - { - SelectedElement.Properties["sensor"] = value; - UpdateMarkupFromElements(); - OnPropertyChanged(nameof(SelectedElementSensor)); - } - } - } - - // Lists for populating pickers - public List FontSizes => new List { "1", "2", "3" }; - #endregion #region Commands // Tab selection commands - public ICommand SwitchToVisualEditorCommand { get; } public ICommand SwitchToMarkupEditorCommand { get; } public ICommand SwitchToTemplatesCommand { get; } @@ -384,15 +127,6 @@ public class OledConfigViewModel : BaseViewModel public ICommand PreviewCommand { get; } public ICommand ResetCommand { get; } - // Visual editor commands - public ICommand AddElementCommand { get; } - public ICommand DeleteElementCommand { get; } - public ICommand ZoomInCommand { get; } - public ICommand ZoomOutCommand { get; } - public ICommand FilterSensorsCommand { get; } - public ICommand AddSensorToDisplayCommand { get; } - public ICommand BrowseIconsCommand { get; } - // Markup editor commands public ICommand InsertMarkupCommand { get; } public ICommand InsertSensorVariableCommand { get; } @@ -416,10 +150,8 @@ public class OledConfigViewModel : BaseViewModel _serialPortService = serialPortService ?? throw new ArgumentNullException(nameof(serialPortService)); // Initialize collections - _oledElements = new ObservableCollection(); _previewElements = new List(); _availableSensors = new ObservableCollection(); - _filteredSensors = new ObservableCollection(); _templateList = new ObservableCollection