Mejorada la implementacion de rotacion y redimensionado.

This commit is contained in:
Miguel 2024-06-28 19:47:08 +02:00
parent 2fe1af47dc
commit e09e4e710a
45 changed files with 880 additions and 681 deletions

View File

@ -44,6 +44,10 @@
<None Remove="Icons\duplicate.png" />
<None Remove="Icons\extract.png" />
<None Remove="Icons\fotocelula.png" />
<None Remove="Icons\rotation.cur" />
<None Remove="Icons\rotation32x32.cur" />
<None Remove="Icons\rotationRx.cur" />
<None Remove="Icons\rotationSx.cur" />
<None Remove="Icons\save.png" />
<None Remove="Icons\start.png" />
<None Remove="Icons\stop.png" />
@ -85,6 +89,10 @@
<PackageReference Include="Tesseract.Drawing" Version="5.2.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Libraries\LibS7Adv\LibS7Adv.csproj" />
</ItemGroup>
<ItemGroup>
<Reference Include="Siemens.Simatic.Simulation.Runtime.Api.x64">
<HintPath>C:\Program Files (x86)\Common Files\Siemens\PLCSIMADV\API\6.0\Siemens.Simatic.Simulation.Runtime.Api.x64.dll</HintPath>
@ -111,6 +119,8 @@
<CopyToOutputDirectory></CopyToOutputDirectory>
</Resource>
<Resource Include="Icons\fotocelula.png" />
<Resource Include="Icons\rotationRx.cur" />
<Resource Include="Icons\rotationSx.cur" />
<Resource Include="Icons\save.png" />
<Resource Include="Icons\start.png" />
<Resource Include="Icons\stop.png" />

View File

@ -3,7 +3,9 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.9.34723.18
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CtrEditor", "CtrEditor.csproj", "{A4DC96D9-6C55-42ED-8E29-DCBC8D7AB831}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CtrEditor", "CtrEditor.csproj", "{A4DC96D9-6C55-42ED-8E29-DCBC8D7AB831}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LibS7Adv", "..\Libraries\LibS7Adv\LibS7Adv.csproj", "{86A7FED2-AEB1-4766-819F-C6256FA7DD38}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -15,6 +17,10 @@ Global
{A4DC96D9-6C55-42ED-8E29-DCBC8D7AB831}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A4DC96D9-6C55-42ED-8E29-DCBC8D7AB831}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A4DC96D9-6C55-42ED-8E29-DCBC8D7AB831}.Release|Any CPU.Build.0 = Release|Any CPU
{86A7FED2-AEB1-4766-819F-C6256FA7DD38}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{86A7FED2-AEB1-4766-819F-C6256FA7DD38}.Debug|Any CPU.Build.0 = Debug|Any CPU
{86A7FED2-AEB1-4766-819F-C6256FA7DD38}.Release|Any CPU.ActiveCfg = Release|Any CPU
{86A7FED2-AEB1-4766-819F-C6256FA7DD38}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@ -0,0 +1,38 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
namespace CtrEditor.FuncionesBase
{
public struct MutableRect
{
public float Left { get; set; }
public float Top { get; set; }
public float Right { get; set; }
public float Bottom { get; set; }
public MutableRect(float left, float top, float right, float bottom)
{
Left = left;
Top = top;
Right = right;
Bottom = bottom;
}
public MutableRect(Rect r)
{
Left = (float) r.Left;
Top = (float)r.Top;
Right = (float)r.Right;
Bottom = (float)r.Bottom;
}
public float Width => Right - Left;
public float Height => Bottom - Top;
}
}

BIN
Icons/rotationRx.cur Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

BIN
Icons/rotationSx.cur Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@ -5,7 +5,7 @@ using Ookii.Dialogs.Wpf;
using System.Collections.ObjectModel;
using System.Windows.Threading;
using CtrEditor.ObjetosSim;
using CtrEditor.Siemens;
using LibS7Adv;
using System.IO;
using Newtonsoft.Json;
using System.Windows;
@ -18,6 +18,7 @@ using CtrEditor.ObjetosSim.Extraccion_Datos;
using ClosedXML.Excel;
using CtrEditor.PopUps;
using System.Windows.Data;
using CommunityToolkit.Mvvm.Input;
namespace CtrEditor
@ -36,9 +37,15 @@ namespace CtrEditor
public SimulationManagerFP simulationManager = new SimulationManagerFP();
private readonly DispatcherTimer _timerSimulacion;
private readonly DispatcherTimer _timerPLCUpdate;
public Canvas MainCanvas;
public bool IsConnected
{
get => PLCViewModel.IsConnected;
}
[ObservableProperty]
private DatosDeTrabajo datosDeTrabajo;
@ -101,14 +108,6 @@ namespace CtrEditor
CommandManager.InvalidateRequerySuggested(); // Notificar que el estado de los comandos ha cambiado
}
[ObservableProperty]
private bool isConnected;
partial void OnIsConnectedChanged(bool value)
{
CommandManager.InvalidateRequerySuggested();
}
public string directorioTrabajo
{
get => EstadoPersistente.Instance.directorio;
@ -133,6 +132,12 @@ namespace CtrEditor
}
}
[RelayCommand]
public void DebugWindow()
{
MainWindow.DebugWindow();
}
[ObservableProperty]
private PLCViewModel pLCViewModel;
@ -202,7 +207,10 @@ namespace CtrEditor
// Inicializa el PLCViewModel
PLCViewModel = new PLCViewModel();
PLCViewModel.RefreshEvent += OnRefreshEvent;
_timerPLCUpdate = new DispatcherTimer();
_timerPLCUpdate.Interval = TimeSpan.FromMilliseconds(100); // ajusta el intervalo según sea necesario
_timerPLCUpdate.Tick += OnRefreshEvent;
InitializeTipoSimulableList();
@ -218,8 +226,8 @@ namespace CtrEditor
TBStartSimulationCommand = new RelayCommand(StartSimulation, () => !IsSimulationRunning);
TBStopSimulationCommand = new RelayCommand(StopSimulation, () => IsSimulationRunning);
TBSaveCommand = new RelayCommand(Save);
TBConnectPLCCommand = new RelayCommand(ConnectPLC, () => !IsConnected);
TBDisconnectPLCCommand = new RelayCommand(DisconnectPLC, () => IsConnected);
TBConnectPLCCommand = new RelayCommand(ConnectPLC, () => !PLCViewModel.IsConnected);
TBDisconnectPLCCommand = new RelayCommand(DisconnectPLC, () => PLCViewModel.IsConnected);
TBEliminarUserControlCommand = new RelayCommand(EliminarUserControl, () => habilitarEliminarUserControl);
TBDuplicarUserControlCommand = new RelayCommand(DuplicarUserControl, () => habilitarEliminarUserControl);
@ -707,13 +715,16 @@ namespace CtrEditor
private void ConnectPLC()
{
_timerPLCUpdate.Start();
PLCViewModel.Connect();
foreach (var objetoSimulable in ObjetosSimulables)
objetoSimulable.SetPLC(PLCViewModel);
}
private void DisconnectPLC()
{
PLCViewModel.Disconnect();
IsConnected = false;
_timerPLCUpdate.Stop();
foreach (var objetoSimulable in ObjetosSimulables)
objetoSimulable.SetPLC(null);
@ -723,12 +734,6 @@ namespace CtrEditor
{
if (PLCViewModel.IsConnected)
{
if (!isConnected)
{
IsConnected = true;
foreach (var objetoSimulable in ObjetosSimulables)
objetoSimulable.SetPLC(PLCViewModel.PLCInterface);
}
// Detener el cronómetro y obtener el tiempo transcurrido en milisegundos
var elapsedMilliseconds = stopwatch_Sim.Elapsed.TotalMilliseconds - stopwatch_SimPLC_last;
stopwatch_SimPLC_last = stopwatch_Sim.Elapsed.TotalMilliseconds;
@ -736,7 +741,7 @@ namespace CtrEditor
// Reiniciar el cronómetro para la próxima medición
foreach (var objetoSimulable in ObjetosSimulables)
objetoSimulable.UpdatePLC(PLCViewModel.PLCInterface, (int)elapsedMilliseconds);
objetoSimulable.UpdatePLC(PLCViewModel, (int)elapsedMilliseconds);
}
}
@ -867,9 +872,6 @@ namespace CtrEditor
PixelToMeter.Instance.calc = simulationData.UnitConverter;
// Re-register to the events
PLCViewModel.RefreshEvent += OnRefreshEvent;
}
}
@ -887,7 +889,11 @@ namespace CtrEditor
}
// Recorrer la colección de objetos simulables
foreach (var objetoSimulable in ObjetosSimulables)
if (objetoSimulable != null) CrearUserControlDesdeObjetoSimulable(objetoSimulable);
if (objetoSimulable != null)
{
objetoSimulable.CheckData();
CrearUserControlDesdeObjetoSimulable(objetoSimulable);
}
}
}
catch { /* Consider logging the error or handling it appropriately */ }

View File

@ -1,6 +1,6 @@
<Window xmlns:ctreditor="clr-namespace:CtrEditor" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:i="http://schemas.microsoft.com/xaml/behaviors" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Siemens="clr-namespace:CtrEditor.Siemens" xmlns:local="clr-namespace:CtrEditor"
xmlns:Siemens="clr-namespace:LibS7Adv;assembly=LibS7Adv" xmlns:local="clr-namespace:CtrEditor"
xmlns:uc="clr-namespace:CtrEditor.ObjetosSim.UserControls"
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit" xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:ObjetosSim="clr-namespace:CtrEditor.ObjetosSim"
@ -43,6 +43,7 @@
<MenuItem Header="Abrir Directorio de trabajo" Command="{Binding OpenWorkDirectoryCommand}" />
<MenuItem Header="Iniciar Simulacion" Command="{Binding StartSimulationCommand}" />
<MenuItem Header="Detenet Simulacion" Command="{Binding StopSimulationCommand}" />
<MenuItem Header="Debug Window" Command="{Binding DebugWindowCommand}" />
<MenuItem Header="Guardar" Command="{Binding SaveCommand}" />
<MenuItem Header="Salir" Command="{Binding ExitCommand}" />
</MenuItem>
@ -51,7 +52,7 @@
<Grid Margin="0,20,0,0">
<!-- Margen superior para el menú -->
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" MinWidth="100" />
<ColumnDefinition Width="1*" MinWidth="200" />
<ColumnDefinition Width="8*" MinWidth="200" />
<ColumnDefinition Width="2*" MinWidth="100" />
</Grid.ColumnDefinitions>

View File

@ -11,7 +11,9 @@ using System.Windows.Threading;
using System.Diagnostics;
using CtrEditor.ObjetosSim.UserControls;
using DocumentFormat.OpenXml.Spreadsheet;
using System.Windows.Shapes;
using System.Numerics;
using CommunityToolkit.Mvvm.Input;
namespace CtrEditor
{
@ -27,6 +29,8 @@ namespace CtrEditor
private bool _isDraggingCanvas = false;
private Image imagenDeFondo;
private List<Rectangle> resizeRectangles = new List<Rectangle>();
private DispatcherTimer _zoomTimer;
private double _targetZoomFactor;
private double _initialZoomFactor;
@ -74,27 +78,6 @@ namespace CtrEditor
}
}
public (float X, float Y) ObtenerCentroCanvasPixels()
{
var scaleTransform = ImagenEnTrabajoCanvas.LayoutTransform as ScaleTransform;
float scaleX = (float)(scaleTransform?.ScaleX ?? 1.0);
float scaleY = (float)(scaleTransform?.ScaleY ?? 1.0);
// Obtiene el área visible del ScrollViewer
float visibleWidth = (float)ImagenEnTrabajoScrollViewer.ViewportWidth;
float visibleHeight = (float)ImagenEnTrabajoScrollViewer.ViewportHeight;
// Obtiene la posición actual del desplazamiento ajustada por el zoom
float offsetX = (float)ImagenEnTrabajoScrollViewer.HorizontalOffset / scaleX;
float offsetY = (float)ImagenEnTrabajoScrollViewer.VerticalOffset / scaleY;
// Calcula el centro visible ajustado
float centerX = offsetX + (visibleWidth / scaleX) / 2;
float centerY = offsetY + (visibleHeight / scaleY) / 2;
return (centerX, centerY);
}
public (float X, float Y) ObtenerCentroCanvasMeters()
{
var c = ObtenerCentroCanvasPixels();
@ -136,10 +119,21 @@ namespace CtrEditor
{
if (!_isDrawingCanvas)
{
var userControl = sender as UserControl;
_currentDraggingControl = userControl;
userControl.CaptureMouse(); // Importante para recibir eventos de movimiento incluso fuera del control
if (resizeRectangles != null && resizeRectangles.Contains(sender))
{
_isResizingUserControl = true;
lastMousePosition = e.GetPosition(ImagenEnTrabajoCanvas);
((Rectangle)sender).CaptureMouse();
_isMovingUserControl = true;
lastAngle = 0;
}
else
{
var userControl = sender as UserControl;
userControl.CaptureMouse(); // Importante para recibir eventos de movimiento incluso fuera del control
_currentDraggingControl = userControl;
_isMovingUserControl = true;
RemoveResizeRectangles();
if (sender is UserControl control && control.DataContext is osBase datos)
{
@ -191,6 +185,7 @@ namespace CtrEditor
{
// Inicializar el cambio de tamaño
_isResizingUserControl = true;
_startPointUserControl = e.GetPosition(ImagenEnTrabajoCanvas);
}
// MOVIMIENTO
else
@ -201,15 +196,208 @@ namespace CtrEditor
}
}
}
}
dataDebug dataDebug = new dataDebug();
public void DebugWindow()
{
// Crear una instancia de wDebug
var debugWindow = new wDebug
{
Data = dataDebug // Asignar la instancia de Test a la propiedad Data
};
// Mostrar la ventana de depuración
debugWindow.Show();
}
private Point transformedBoundingBoxCenter = new Point();
private float lastAngle;
private System.Threading.Timer timerRemoveResizeRectangles = null;
public void ResetTimerRemoveResizeRectangles()
{
if (timerRemoveResizeRectangles == null)
timerRemoveResizeRectangles = new System.Threading.Timer(TimerCallbackRemoveResizeRectangles, null, Timeout.Infinite, Timeout.Infinite);
timerRemoveResizeRectangles.Change(2000, Timeout.Infinite);
}
private async void TimerCallbackRemoveResizeRectangles(object state)
{
Application.Current.Dispatcher.Invoke(() =>
{
// Realiza tus cambios en la interfaz de usuario aquí
MakeResizeRectanglesTransparent();
});
}
public void PauseTimerRemoveResizeRectangles()
{
if (timerRemoveResizeRectangles != null)
{
timerRemoveResizeRectangles.Change(Timeout.Infinite, Timeout.Infinite);
}
}
private void AddResizeRectangles(UserControl userControl)
{
double rectSize = 10;
RemoveResizeRectangles();
// Obtener el BoundingBox aproximado del UserControl
Rect boundingBox = VisualTreeHelper.GetDescendantBounds(userControl);
// Transformar el BoundingBox a las coordenadas del Canvas
GeneralTransform transform = userControl.TransformToAncestor(ImagenEnTrabajoCanvas);
Rect transformedBoundingBox = transform.TransformBounds(boundingBox);
FuncionesBase.MutableRect rectBox = new FuncionesBase.MutableRect(transformedBoundingBox);
rectBox.Left -= (float)rectSize;
rectBox.Right += (float)rectSize;
rectBox.Top -= (float)rectSize;
rectBox.Bottom += (float)rectSize;
transformedBoundingBoxCenter.X = transformedBoundingBox.Left + transformedBoundingBox.Width / 2;
transformedBoundingBoxCenter.Y = transformedBoundingBox.Top + transformedBoundingBox.Height / 2;
// Cargar el cursor personalizado para rotación
Cursor rotationCursorRx = new Cursor(Application.GetResourceStream(new Uri("pack://application:,,,/CtrEditor;component/Icons/rotationRx.cur")).Stream);
Cursor rotationCursorSx = new Cursor(Application.GetResourceStream(new Uri("pack://application:,,,/CtrEditor;component/Icons/rotationSx.cur")).Stream);
// Calcular las posiciones de los rectángulos de redimensionamiento
var positions = new List<Tuple<Point, string>>()
{
new Tuple<Point, string>(new Point(rectBox.Left, rectBox.Top), "TopLeft"),
new Tuple<Point, string>(new Point(rectBox.Right, rectBox.Top), "TopRight"),
new Tuple<Point, string>(new Point(rectBox.Left, rectBox.Bottom), "BottomLeft"),
new Tuple<Point, string>(new Point(rectBox.Right, rectBox.Bottom), "BottomRight"),
new Tuple<Point, string>(new Point(rectBox.Left + rectBox.Width / 2, rectBox.Top), "TopCenter"),
new Tuple<Point, string>(new Point(rectBox.Left + rectBox.Width / 2, rectBox.Bottom), "BottomCenter"),
new Tuple<Point, string>(new Point(rectBox.Left, rectBox.Top + rectBox.Height / 2), "CenterLeft"),
new Tuple<Point, string>(new Point(rectBox.Right, rectBox.Top + rectBox.Height / 2), "CenterRight")
};
foreach (var position in positions)
{
Rectangle rect = new Rectangle
{
Width = rectSize,
Height = rectSize,
Fill = Brushes.Transparent,
Stroke = Brushes.Black,
StrokeThickness = 1,
Tag = position.Item2 // Asignar la etiqueta
};
// Establecer el cursor adecuado
switch (position.Item2)
{
case "TopLeft":
rect.Cursor = Cursors.Arrow;
break;
case "TopRight":
rect.Cursor = rotationCursorRx; // Cursor de rotación
break;
case "BottomLeft":
rect.Cursor = rotationCursorSx; // Cursor de rotación
break;
case "BottomRight":
rect.Cursor = Cursors.SizeNWSE; // Cursor de dimensionar altura y anchura
break;
case "TopCenter":
rect.Cursor = Cursors.Arrow;
break;
case "BottomCenter":
rect.Cursor = Cursors.SizeNS; // Cursor de dimensionar altura
break;
case "CenterLeft":
rect.Cursor = rotationCursorRx; // Cursor de rotación
break;
case "CenterRight":
rect.Cursor = Cursors.SizeWE; // Cursor de dimensionar anchura
break;
}
Canvas.SetLeft(rect, position.Item1.X - rectSize / 2);
Canvas.SetTop(rect, position.Item1.Y - rectSize / 2);
rect.MouseLeftButtonDown += UserControl_MouseLeftButtonDown;
rect.MouseMove += UserControl_MouseMove;
rect.MouseLeftButtonUp += UserControl_MouseLeftButtonUp;
rect.MouseLeave += ResizeRectangle_MouseLeave;
resizeRectangles.Add(rect);
ImagenEnTrabajoCanvas.Children.Add(rect);
ResetTimerRemoveResizeRectangles();
}
}
private void ResizeRectangle_MouseLeave(object sender, MouseEventArgs e)
{
var rect = sender as Rectangle;
rect.Fill = Brushes.Transparent; // Volver al color original
ResetTimerRemoveResizeRectangles();
}
private void MakeResizeRectanglesTransparent()
{
if (resizeRectangles == null || resizeRectangles.Count == 0)
return;
foreach (var rect in resizeRectangles)
{
rect.Opacity = 0; // Hacer transparente
}
}
private void MakeResizeRectanglesNormal()
{
if (resizeRectangles == null || resizeRectangles.Count == 0)
return;
foreach (var rect in resizeRectangles)
{
rect.Opacity = 1;
}
}
private void RemoveResizeRectangles()
{
if (resizeRectangles == null || resizeRectangles.Count == 0)
return;
foreach (var rect in resizeRectangles)
{
ImagenEnTrabajoCanvas.Children.Remove(rect);
}
resizeRectangles.Clear();
}
private Point lastMousePosition;
private void UserControl_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
if (_isMovingUserControl)
if (_isResizingUserControl && resizeRectangles != null && resizeRectangles.Contains(sender))
{
_isResizingUserControl = false;
_isMovingUserControl = false;
((Rectangle)sender).ReleaseMouseCapture();
AddResizeRectangles(_currentDraggingControl);
}
else if (_isMovingUserControl)
{
var userControl = sender as UserControl;
userControl.ReleaseMouseCapture();
_currentDraggingControl = null;
// _currentDraggingControl = null;
AddResizeRectangles(_currentDraggingControl);
_isResizingUserControl = _isRotatingUserControl = _isDraggingUserControl = false;
_isMovingUserControl = false;
// Ocultar el TextBlock de ángulo
@ -220,8 +408,19 @@ namespace CtrEditor
}
}
Rectangle _currentDraggingRectangle;
private void UserControl_MouseMove(object sender, MouseEventArgs e)
{
if (!_isMovingUserControl && resizeRectangles != null && resizeRectangles.Contains(sender))
{
var rect = sender as Rectangle;
rect.Fill = Brushes.Black; // Pintar de negro el rectángulo bajo el ratón
_currentDraggingRectangle = rect; // Asignar el rectángulo actual que se está arrastrando
_startPointUserControl = new Point(Canvas.GetLeft(rect), Canvas.GetTop(rect));
MakeResizeRectanglesNormal();
PauseTimerRemoveResizeRectangles();
}
if (_isMovingUserControl && _currentDraggingControl != null)
{
var currentPosition = e.GetPosition(ImagenEnTrabajoCanvas);
@ -249,7 +448,6 @@ namespace CtrEditor
// Código para cambiar el tamaño del control
ResizeControl(_currentDraggingControl, currentPosition);
}
}
}
@ -278,6 +476,74 @@ namespace CtrEditor
}
private void ResizeControl(UserControl control, Point currentPosition)
{
bool ActivateRotation = false, ActivateSizeWidth = false, ActivateSizeHeight = false, ActivateMove = false;
if (control is IDataContainer dataContainer)
{
MakeResizeRectanglesTransparent();
// Obtener el rectángulo desde el que se inició la redimensión
var resizeRect = _currentDraggingRectangle as Rectangle;
if (resizeRect == null) return;
string resizeDirection = resizeRect.Tag as string;
if (resizeDirection == null) return;
switch (resizeDirection)
{
case "TopLeft":
break;
case "TopRight":
ActivateRotation = true;
break;
case "BottomLeft":
ActivateRotation = true;
break;
case "BottomRight":
ActivateSizeHeight = true;
ActivateSizeWidth = true;
break;
case "TopCenter":
break;
case "BottomCenter":
ActivateSizeHeight = true;
break;
case "CenterLeft":
ActivateRotation = true;
break;
case "CenterRight":
ActivateSizeWidth = true;
break;
}
if (ActivateMove)
{
// Código para mover el control
var dx = currentPosition.X - _startPointUserControl.X;
var dy = currentPosition.Y - _startPointUserControl.Y;
var newX = Canvas.GetLeft(_currentDraggingControl) + dx;
var newY = Canvas.GetTop(_currentDraggingControl) + dy;
dataContainer.Move((float)newX, (float)newY);
}
if (ActivateRotation)
{
double deltaX = currentPosition.X - transformedBoundingBoxCenter.X;
double deltaY = currentPosition.Y - transformedBoundingBoxCenter.Y;
double angle = Math.Atan2(deltaY, deltaX) * (180 / Math.PI);
if (lastAngle == 0 && angle != 0) lastAngle = (float)angle;
dataContainer.Rotate((float)angle - lastAngle);
lastAngle = (float)angle;
dataDebug.TransformedBoundingBoxCenter = transformedBoundingBoxCenter;
dataDebug.LastAngle = lastAngle;
dataDebug.CurrentPosition = currentPosition;
dataDebug.Angle = (float)angle;
}
if (ActivateSizeWidth || ActivateSizeHeight)
{
// Calcular la diferencia en la posición X desde el punto de inicio
double widthChange = currentPosition.X - _startPointUserControl.X;
@ -285,31 +551,30 @@ namespace CtrEditor
// Calcular la diferencia en la posición Y desde el punto de inicio
double heightChange = currentPosition.Y - _startPointUserControl.Y;
// Actualizar el ancho del control
double newWidth = Math.Max(control.ActualWidth + widthChange, control.MinWidth);
if (!ActivateSizeHeight) heightChange = 0;
if (!ActivateSizeWidth) widthChange = 0;
// Actualizar la altura del control
double newHeight = Math.Max(control.ActualHeight + heightChange, control.MinHeight);
// Asegurar que el nuevo tamaño no sea menor que los mínimos
control.Width = newWidth;
control.Height = newHeight;
if (control is IDataContainer dataContainer)
{
dataContainer.Resize((float)newWidth, (float)newHeight);
dataContainer.Resize((float)widthChange, (float)heightChange);
}
_startPointUserControl = currentPosition; // Actualiza el punto inicial para el siguiente movimiento
}
// Actualizar el punto de inicio para el próximo evento de movimiento
_startPointUserControl = currentPosition;
}
private void UserControl_MouseEnter(object sender, MouseEventArgs e)
{
if (_currentDraggingControl != null)
{
RemoveResizeRectangles();
}
if (sender is UserControl userControl)
if (userControl is IDataContainer dataContainer)
{
dataContainer.Highlight(true);
_currentDraggingControl = sender as UserControl;
AddResizeRectangles(_currentDraggingControl);
}
}
private void UserControl_MouseLeave(object sender, MouseEventArgs e)
@ -385,6 +650,8 @@ namespace CtrEditor
var dx = currentPosition.X - _lastMousePosition.X;
var dy = currentPosition.Y - _lastMousePosition.Y;
MakeResizeRectanglesTransparent();
// Obtener la transformación actual del Canvas
var transform = (TranslateTransform)((TransformGroup)ImagenEnTrabajoCanvas.RenderTransform).Children.First(t => t is TranslateTransform);
transform.X += dx;
@ -396,6 +663,8 @@ namespace CtrEditor
private void ImagenEnTrabajoCanvas_MouseWheel(object sender, MouseWheelEventArgs e)
{
MakeResizeRectanglesTransparent();
_initialZoomFactor = ((ScaleTransform)((TransformGroup)ImagenEnTrabajoCanvas.RenderTransform).Children.First(t => t is ScaleTransform)).ScaleX;
// Calcula el factor de escala mínimo para que toda la imagen sea visible
@ -462,6 +731,33 @@ namespace CtrEditor
tt.Y = relativeY - cursorPosition.Y * st.ScaleY;
}
public (float X, float Y) ObtenerCentroCanvasPixels()
{
// Obtener las transformaciones actuales del Canvas
var tg = (TransformGroup)ImagenEnTrabajoCanvas.RenderTransform;
var st = (ScaleTransform)tg.Children.First(t => t is ScaleTransform);
var tt = (TranslateTransform)tg.Children.First(t => t is TranslateTransform);
// Obtener el tamaño del ScrollViewer visible
double visibleWidth = ImagenEnTrabajoScrollViewer.ViewportWidth;
double visibleHeight = ImagenEnTrabajoScrollViewer.ViewportHeight;
// Obtener el desplazamiento del ScrollViewer
double offsetX = ImagenEnTrabajoScrollViewer.HorizontalOffset;
double offsetY = ImagenEnTrabajoScrollViewer.VerticalOffset;
// Calcular las coordenadas del centro visible del ScrollViewer
double centerX = offsetX + (visibleWidth / 2);
double centerY = offsetY + (visibleHeight / 2);
// Ajustar las coordenadas del centro para tener en cuenta las transformaciones del Canvas
double canvasCenterX = (centerX - tt.X) / st.ScaleX;
double canvasCenterY = (centerY - tt.Y) / st.ScaleY;
return ((float)canvasCenterX, (float)canvasCenterY);
}
private void CargarPropiedadesosDatos(osBase selectedObject)
{
if (DataContext is MainViewModel viewModel)

View File

@ -95,8 +95,8 @@ namespace CtrEditor.ObjetosSim
{
if (Datos is osTextPlate datos)
{
datos.Ancho = PixelToMeter.Instance.calc.PixelsToMeters(width);
datos.Alto = PixelToMeter.Instance.calc.PixelsToMeters(height);
datos.Ancho += PixelToMeter.Instance.calc.PixelsToMeters(width);
datos.Alto += PixelToMeter.Instance.calc.PixelsToMeters(height);
}
}
public void Move(float LeftPixels, float TopPixels)
@ -111,7 +111,7 @@ namespace CtrEditor.ObjetosSim
{
if (Datos != null)
if (Datos is osTextPlate datos)
datos.Angulo = Angle;
datos.Angulo += Angle;
}
public void Highlight(bool State) { }
public int ZIndex()

View File

@ -2,7 +2,7 @@
using System.Windows.Controls;
//using using Microsoft.Xna.Framework;
using CtrEditor.Siemens;
using LibS7Adv;
using CtrEditor.Simulacion;
using CommunityToolkit.Mvvm.ComponentModel;
using nkast.Aether.Physics2D.Common;

View File

@ -2,7 +2,7 @@
using System.Windows.Controls;
//using using Microsoft.Xna.Framework;
using CtrEditor.Siemens;
using LibS7Adv;
using CtrEditor.Simulacion;
using CommunityToolkit.Mvvm.ComponentModel;
using nkast.Aether.Physics2D.Common;

View File

@ -1,4 +1,4 @@
using CtrEditor.Siemens;
using LibS7Adv;
using System.Windows;
using System.Windows.Controls;
using CommunityToolkit.Mvvm.ComponentModel;
@ -87,7 +87,7 @@ namespace CtrEditor.ObjetosSim
Filtro_consenso_s = 1;
}
public override void UpdatePLC(PLCModel plc, int elapsedMilliseconds)
public override void UpdatePLC(PLCViewModel plc, int elapsedMilliseconds)
{
if (Consenso_NC)
Consenso = !LeerBitTag(Tag_consenso);
@ -180,8 +180,8 @@ namespace CtrEditor.ObjetosSim
{
if (Datos is osBottGenerator datos)
{
datos.Ancho = PixelToMeter.Instance.calc.PixelsToMeters(width);
datos.Alto = PixelToMeter.Instance.calc.PixelsToMeters(width);
datos.Ancho += PixelToMeter.Instance.calc.PixelsToMeters(width);
datos.Alto += PixelToMeter.Instance.calc.PixelsToMeters(width);
}
}
public void Move(float LeftPixels, float TopPixels)
@ -196,7 +196,7 @@ namespace CtrEditor.ObjetosSim
{
if (Datos != null)
if (Datos is osBottGenerator datos)
datos.Angulo = Angle;
datos.Angulo += Angle;
}
public void Highlight(bool State) { }
public int ZIndex()

View File

@ -15,7 +15,7 @@
<Image Source="/imagenes/filler.png"
Width="{Binding Ancho, Converter={StaticResource MeterToPixelConverter}}"
Height="{Binding Alto, Converter={StaticResource MeterToPixelConverter}}"
Stretch="Uniform">
Stretch="Fill">
<Image.RenderTransform>
<RotateTransform Angle="{Binding Angulo}" />
</Image.RenderTransform>

View File

@ -1,5 +1,5 @@

using CtrEditor.Siemens;
using LibS7Adv;
using System.Windows;
using System.Windows.Controls;
using CommunityToolkit.Mvvm.ComponentModel;
@ -88,7 +88,7 @@ namespace CtrEditor.ObjetosSim
Filtro_consenso_s = 1;
}
public override void UpdatePLC(PLCModel plc, int elapsedMilliseconds)
public override void UpdatePLC(PLCViewModel plc, int elapsedMilliseconds)
{
if (Consenso_NC)
Consenso = !LeerBitTag(Tag_consenso);
@ -181,8 +181,8 @@ namespace CtrEditor.ObjetosSim
{
if (Datos is osFiller datos)
{
datos.Ancho = PixelToMeter.Instance.calc.PixelsToMeters(width);
datos.Alto = PixelToMeter.Instance.calc.PixelsToMeters(width);
datos.Ancho += PixelToMeter.Instance.calc.PixelsToMeters(width);
datos.Alto += PixelToMeter.Instance.calc.PixelsToMeters(height);
}
}
public void Move(float LeftPixels, float TopPixels)
@ -197,7 +197,7 @@ namespace CtrEditor.ObjetosSim
{
if (Datos != null)
if (Datos is osFiller datos)
datos.Angulo = Angle;
datos.Angulo += Angle;
}
public void Highlight(bool State) { }
public int ZIndex()

View File

@ -1,6 +1,6 @@
using CommunityToolkit.Mvvm.ComponentModel;
using CtrEditor.Siemens;
using LibS7Adv;
using System.Windows;
using System.Windows.Controls;
@ -61,7 +61,7 @@ namespace CtrEditor.ObjetosSim
Min_OUT_Scaled = 0;
}
public override void UpdatePLC(PLCModel plc, int elapsedMilliseconds)
public override void UpdatePLC(PLCViewModel plc, int elapsedMilliseconds)
{
EscribirWordTagScaled(TagNivel_Word, Level, 0, 100, Min_OUT_Scaled, Max_OUT_Scaled);
Ingreso_Abierto = LeerBitTag(TagIngresoAbierto_Bool);
@ -114,8 +114,8 @@ namespace CtrEditor.ObjetosSim
{
if (Datos is osTanque datos)
{
datos.Ancho = PixelToMeter.Instance.calc.PixelsToMeters(width);
datos.Alto = PixelToMeter.Instance.calc.PixelsToMeters(width);
datos.Ancho += PixelToMeter.Instance.calc.PixelsToMeters(width);
datos.Alto += PixelToMeter.Instance.calc.PixelsToMeters(width);
}
}
public void Move(float LeftPixels, float TopPixels)
@ -130,7 +130,7 @@ namespace CtrEditor.ObjetosSim
{
if (Datos != null)
if (Datos is osTanque datos)
datos.Angulo = Angle;
datos.Angulo += Angle;
}
public void Highlight(bool State) { }
public int ZIndex()

View File

@ -1,5 +1,5 @@

using CtrEditor.Siemens;
using LibS7Adv;
using CtrEditor.Simulacion;
using System.Windows;
using System.Windows.Controls;
@ -82,7 +82,7 @@ namespace CtrEditor.ObjetosSim
public override void UpdateGeometryStep()
{
}
public override void UpdatePLC(PLCModel plc, int elapsedMilliseconds)
public override void UpdatePLC(PLCViewModel plc, int elapsedMilliseconds)
{
}
@ -133,7 +133,7 @@ namespace CtrEditor.ObjetosSim
{
if (Datos is osDescarte datos)
{
datos.Diametro = PixelToMeter.Instance.calc.PixelsToMeters(width);
datos.Diametro += PixelToMeter.Instance.calc.PixelsToMeters(width+ height);
}
}
public void Move(float LeftPixels, float TopPixels)

View File

@ -2,7 +2,7 @@
using System.Windows.Controls;
using CommunityToolkit.Mvvm.ComponentModel;
using CtrEditor.Siemens;
using LibS7Adv;
using CtrEditor.Simulacion;
namespace CtrEditor.ObjetosSim
@ -57,7 +57,7 @@ namespace CtrEditor.ObjetosSim
public override void UpdateGeometryStep()
{
}
public override void UpdatePLC(PLCModel plc, int elapsedMilliseconds) { }
public override void UpdatePLC(PLCViewModel plc, int elapsedMilliseconds) { }
public override void ucLoaded()
{
// El UserControl ya se ha cargado y podemos obtener las coordenadas para
@ -98,7 +98,7 @@ namespace CtrEditor.ObjetosSim
public void Resize(float width, float height)
{
if (Datos is osGuia datos)
datos.Ancho = PixelToMeter.Instance.calc.PixelsToMeters(width);
datos.Ancho += PixelToMeter.Instance.calc.PixelsToMeters(width);
}
public void Move(float LeftPixels, float TopPixels)
{
@ -112,7 +112,7 @@ namespace CtrEditor.ObjetosSim
{
if (Datos != null)
if (Datos is osGuia datos)
datos.Angulo = Angle;
datos.Angulo += Angle;
}
public void Highlight(bool State) { }
public int ZIndex()

View File

@ -2,7 +2,7 @@
using System.Windows;
using System.Windows.Controls;
using CommunityToolkit.Mvvm.ComponentModel;
using CtrEditor.Siemens;
using LibS7Adv;
using CtrEditor.Simulacion;
using Xceed.Wpf.Toolkit.PropertyGrid.Attributes;
@ -131,7 +131,7 @@ namespace CtrEditor.ObjetosSim
}
public override void UpdatePLC(PLCModel plc, int elapsedMilliseconds)
public override void UpdatePLC(PLCViewModel plc, int elapsedMilliseconds)
{
if (Motor != null)
{
@ -186,8 +186,8 @@ namespace CtrEditor.ObjetosSim
{
if (RadioExterno > RadioInterno && RadioExterno > 0 && RadioInterno >= 0)
{
datos.RadioExterno = PixelToMeter.Instance.calc.PixelsToMeters(RadioExterno);
datos.RadioInterno = PixelToMeter.Instance.calc.PixelsToMeters(RadioInterno);
datos.RadioExterno += PixelToMeter.Instance.calc.PixelsToMeters(RadioExterno);
datos.RadioInterno += PixelToMeter.Instance.calc.PixelsToMeters(RadioInterno);
}
}
}
@ -203,7 +203,7 @@ namespace CtrEditor.ObjetosSim
{
if (Datos != null)
if (Datos is osTransporteCurva datos)
datos.Angulo = Angle;
datos.Angulo += Angle;
}
public void Highlight(bool State) { }
public int ZIndex()

View File

@ -3,7 +3,7 @@ using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using CommunityToolkit.Mvvm.ComponentModel;
using CtrEditor.Siemens;
using LibS7Adv;
using CtrEditor.Simulacion;
using Xceed.Wpf.Toolkit.PropertyGrid.Attributes;
@ -160,7 +160,7 @@ namespace CtrEditor.ObjetosSim
// Se llama al detener la simulacion
ActualizarAnimacionStoryBoardTransporte(VelocidadActual);
}
public override void UpdatePLC(PLCModel plc, int elapsedMilliseconds)
public override void UpdatePLC(PLCViewModel plc, int elapsedMilliseconds)
{
if (Motor != null)
if (Motor is osVMmotorSim id_motor)
@ -220,7 +220,7 @@ namespace CtrEditor.ObjetosSim
public void Resize(float width, float height)
{
if (Datos is osTransporteGuias datos)
datos.Ancho = PixelToMeter.Instance.calc.PixelsToMeters(width);
datos.Ancho += PixelToMeter.Instance.calc.PixelsToMeters(width);
}
public void Move(float LeftPixels, float TopPixels)
{
@ -234,7 +234,7 @@ namespace CtrEditor.ObjetosSim
{
if (Datos != null)
if (Datos is osTransporteGuias datos)
datos.Angulo = Angle;
datos.Angulo += Angle;
}
public void Highlight(bool State) { }
public int ZIndex()

View File

@ -5,7 +5,7 @@ using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using CommunityToolkit.Mvvm.ComponentModel;
using CtrEditor.Siemens;
using LibS7Adv;
using CtrEditor.Simulacion;
using Xceed.Wpf.Toolkit.PropertyGrid.Attributes;
@ -263,7 +263,7 @@ namespace CtrEditor.ObjetosSim
}
}
public override void UpdatePLC(PLCModel plc, int elapsedMilliseconds)
public override void UpdatePLC(PLCViewModel plc, int elapsedMilliseconds)
{
if (_osMotorA != null)
{
@ -387,7 +387,7 @@ namespace CtrEditor.ObjetosSim
public void Resize(float width, float height)
{
if (Datos is osTransporteGuiasUnion datos)
datos.AnchoRecto = PixelToMeter.Instance.calc.PixelsToMeters(width);
datos.AnchoRecto += PixelToMeter.Instance.calc.PixelsToMeters(width);
}
public void Move(float LeftPixels, float TopPixels)
{
@ -401,7 +401,7 @@ namespace CtrEditor.ObjetosSim
{
if (Datos != null)
if (Datos is osTransporteGuiasUnion datos)
datos.Angulo = Angle;
datos.Angulo += Angle;
}
public void Highlight(bool State) { }
public int ZIndex()

View File

@ -1,7 +1,7 @@
using System.Windows;
using System.Windows.Controls;
using CommunityToolkit.Mvvm.ComponentModel;
using CtrEditor.Siemens;
using LibS7Adv;
using CtrEditor.Simulacion;
using Xceed.Wpf.Toolkit.PropertyGrid.Attributes;
using System.ComponentModel;
@ -141,7 +141,7 @@ namespace CtrEditor.ObjetosSim
ActualizarGeometrias();
}
public override void UpdatePLC(PLCModel plc, int elapsedMilliseconds)
public override void UpdatePLC(PLCViewModel plc, int elapsedMilliseconds)
{
if (Motor != null)
if (Motor is osVMmotorSim motor)
@ -191,7 +191,7 @@ namespace CtrEditor.ObjetosSim
public void Resize(float width, float height)
{
if (Datos is osTransporteTTop datos)
datos.Ancho = PixelToMeter.Instance.calc.PixelsToMeters(width);
datos.Ancho += PixelToMeter.Instance.calc.PixelsToMeters(width);
}
public void Move(float LeftPixels, float TopPixels)
{
@ -205,7 +205,7 @@ namespace CtrEditor.ObjetosSim
{
if (Datos != null)
if (Datos is osTransporteTTop datos)
datos.Angulo = Angle;
datos.Angulo += Angle;
}
public void Highlight(bool State) { }
public int ZIndex()

View File

@ -1,5 +1,5 @@

using CtrEditor.Siemens;
using LibS7Adv;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
@ -46,6 +46,8 @@ namespace CtrEditor.ObjetosSim
[ObservableProperty]
public float max_Speed_for_Ramp;
[ObservableProperty]
bool vFD_Trip_NC;
[ObservableProperty]
public float tiempoRampa;
@ -58,9 +60,22 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
public bool encendido;
bool encendido;
[ObservableProperty]
public int pLC_NumeroMotor;
int pLC_NumeroMotor;
partial void OnPLC_NumeroMotorChanged(int value)
{
if (PLC_DB_Motor==0)
{
PLC_DB_Motor = PLC_NumeroMotor - 30 + 300;
}
}
[ObservableProperty]
int pLC_DB_Motor;
[ObservableProperty]
public float ratio;
@ -90,9 +105,9 @@ namespace CtrEditor.ObjetosSim
// Se llama antes de la simulacion
}
public override void UpdatePLC(PLCModel plc, int elapsedMilliseconds) {
motState.UpdatePLC(plc,PLC_NumeroMotor,Encendido, elapsedMilliseconds);
public override void UpdatePLC(PLCViewModel plc, int elapsedMilliseconds)
{
motState.UpdatePLC(plc, this, elapsedMilliseconds);
Velocidad = (ProporcionalSpeed / 100) * (motState.STATUS_VFD_ACT_Speed_Hz / 10);
}
@ -131,7 +146,14 @@ namespace CtrEditor.ObjetosSim
{
Datos?.ucUnLoaded();
}
public void Resize(float width, float height) { }
public void Resize(float width, float height)
{
if (Datos != null)
if (Datos is osVMmotorSim datos)
{
datos.Tamano += PixelToMeter.Instance.calc.PixelsToMeters( width + height);
}
}
public void Move(float LeftPixels, float TopPixels)
{
if (Datos != null)
@ -140,10 +162,11 @@ namespace CtrEditor.ObjetosSim
Datos.Top = PixelToMeter.Instance.calc.PixelsToMeters(TopPixels);
}
}
public void Rotate(float Angle) {
public void Rotate(float Angle)
{
if (Datos != null)
if (Datos is osVMmotorSim datos)
datos.Angulo = Angle;
datos.Angulo += Angle;
}
public void Highlight(bool State) { }
public int ZIndex()
@ -165,23 +188,21 @@ namespace CtrEditor.ObjetosSim
public bool OUT_Reversal;
public float OUT_OUT_VFD_REQ_Speed_Hz;
public void UpdatePLC(PLCModel plc, int NumeroMotor, bool Encendido, int elapsedMilliseconds)
public void UpdatePLC(PLCViewModel plc, osVMmotorSim Data, int elapsedMilliseconds)
{
var index = 0;
switch (NumeroMotor)
{
case < 100:
index = (int)NumeroMotor - 30 + 300;
break;
}
var DB_Motor = Data.PLC_DB_Motor;
OUT_Run = plc.LeerTagBool($"\"DB MotorSimulate\".Motors[{index}].OUT.Run");
OUT_Reversal = plc.LeerTagBool($"\"DB MotorSimulate\".Motors[{index}].OUT.\"Reversal Direction\"");
OUT_OUT_VFD_REQ_Speed_Hz = (float)plc.LeerTagInt16($"\"DB MotorSimulate\".Motors[{index}].OUT.OUT_VFD_REQ_Speed_Hz");
if (DB_Motor == 0)
return;
OUT_Run = plc.LeerTagBool($"\"DB MotorSimulate\".Motors[{DB_Motor}].OUT.Run");
OUT_Reversal = plc.LeerTagBool($"\"DB MotorSimulate\".Motors[{DB_Motor}].OUT.\"Reversal Direction\"");
OUT_OUT_VFD_REQ_Speed_Hz = (float)plc.LeerTagInt16($"\"DB MotorSimulate\".Motors[{DB_Motor}].OUT.OUT_VFD_REQ_Speed_Hz");
if (Encendido)
if (Data.Encendido)
{
_STATUS_VFD_Ready = true;
Motor_Running = true;
@ -198,13 +219,16 @@ namespace CtrEditor.ObjetosSim
STATUS_VFD_Coasting = false;
}
plc.EscribirTagBool($"\"DB MotorSimulate\".Motors[{index}].STATUS_VFD_Ready", _STATUS_VFD_Ready);
plc.EscribirTagBool($"\"DB MotorSimulate\".Motors[{index}].Motor_Running", Motor_Running);
plc.EscribirTagBool($"\"DB MotorSimulate\".Motors[{index}].STATUS_VFD_Trip", STATUS_VFD_Trip);
plc.EscribirTagBool($"\"DB MotorSimulate\".Motors[{index}].STATUS_VFD_Warning", STATUS_VFD_Warning);
plc.EscribirTagBool($"\"DB MotorSimulate\".Motors[{index}].STATUS_VFD_Coasting", STATUS_VFD_Coasting);
if (Data.VFD_Trip_NC)
STATUS_VFD_Trip = !STATUS_VFD_Trip;
plc.EscribirTagInt16($"\"DB MotorSimulate\".Motors[{index}].STATUS_VFD_ACT_Speed_Hz", (int)STATUS_VFD_ACT_Speed_Hz);
plc.EscribirTagBool($"\"DB MotorSimulate\".Motors[{DB_Motor}].STATUS_VFD_Ready", _STATUS_VFD_Ready);
plc.EscribirTagBool($"\"DB MotorSimulate\".Motors[{DB_Motor}].Motor_Running", Motor_Running);
plc.EscribirTagBool($"\"DB MotorSimulate\".Motors[{DB_Motor}].STATUS_VFD_Trip", STATUS_VFD_Trip);
plc.EscribirTagBool($"\"DB MotorSimulate\".Motors[{DB_Motor}].STATUS_VFD_Warning", STATUS_VFD_Warning);
plc.EscribirTagBool($"\"DB MotorSimulate\".Motors[{DB_Motor}].STATUS_VFD_Coasting", STATUS_VFD_Coasting);
plc.EscribirTagInt16($"\"DB MotorSimulate\".Motors[{DB_Motor}].STATUS_VFD_ACT_Speed_Hz", (int)STATUS_VFD_ACT_Speed_Hz);
}

View File

@ -435,8 +435,8 @@ namespace CtrEditor.ObjetosSim.Extraccion_Datos
{
if (Datos is osBuscarCoincidencias datos)
{
datos.Ancho = PixelToMeter.Instance.calc.PixelsToMeters(width);
datos.Alto = PixelToMeter.Instance.calc.PixelsToMeters(height);
datos.Ancho += PixelToMeter.Instance.calc.PixelsToMeters(width);
datos.Alto += PixelToMeter.Instance.calc.PixelsToMeters(height);
}
}
public void Move(float LeftPixels, float TopPixels)
@ -451,7 +451,7 @@ namespace CtrEditor.ObjetosSim.Extraccion_Datos
{
if (Datos != null)
if (Datos is osBuscarCoincidencias datos)
datos.Angulo = Angle;
datos.Angulo += Angle;
}
public void Highlight(bool State) { }
public int ZIndex()

View File

@ -208,8 +208,8 @@ namespace CtrEditor.ObjetosSim.Extraccion_Datos
{
if (Datos is osExtraccionTag datos)
{
datos.Ancho = PixelToMeter.Instance.calc.PixelsToMeters(width);
datos.Alto = PixelToMeter.Instance.calc.PixelsToMeters(height);
datos.Ancho += PixelToMeter.Instance.calc.PixelsToMeters(width);
datos.Alto += PixelToMeter.Instance.calc.PixelsToMeters(height);
}
}
public void Move(float LeftPixels, float TopPixels)
@ -224,7 +224,7 @@ namespace CtrEditor.ObjetosSim.Extraccion_Datos
{
if (Datos != null)
if (Datos is osExtraccionTag datos)
datos.Angulo = Angle;
datos.Angulo += Angle;
}
public void Highlight(bool State) { }
public int ZIndex()

View File

@ -9,7 +9,7 @@
mc:Ignorable="d">
<UserControl.DataContext>
<vm:osBoton Color="#FFADE6C0" ColorButton_oculto="#FFC72323"/>
<vm:osBoton Color="#FFADE6C0" ColorButton="#FFC72323" Color_Pressed="#FF9A9A9A" />
</UserControl.DataContext>
<Canvas RenderTransformOrigin="0.5,0.5">
@ -29,8 +29,8 @@
Height="{Binding Tamano, Converter={StaticResource MeterToPixelConverter}, ConverterParameter=1.5}"
VerticalAlignment="Top"
HorizontalAlignment="Left"
Background="Gray"/>
<Ellipse Fill="{Binding ColorButton_oculto, Converter={StaticResource ColorToBrushConverter}}"
Background="{Binding Color_Pressed, Converter={StaticResource ColorToBrushConverter}}"/>
<Ellipse Fill="{Binding ColorButton, Converter={StaticResource ColorToBrushConverter}}"
Stroke="Black"
StrokeThickness="2"
Width="{Binding Tamano, Converter={StaticResource MeterToPixelConverter}}"

View File

@ -1,6 +1,6 @@
using CommunityToolkit.Mvvm.ComponentModel;
using CtrEditor.Siemens;
using LibS7Adv;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
@ -32,6 +32,10 @@ namespace CtrEditor.ObjetosSim
[ObservableProperty]
public bool tipo_NC;
[ObservableProperty]
[property: Hidden]
Color color_Pressed;
[ObservableProperty]
Color color_Titulo;
@ -44,7 +48,9 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
private Color colorButton_oculto;
[property: Hidden]
private Color colorButton;
[ObservableProperty]
public float tamano;
@ -57,9 +63,9 @@ namespace CtrEditor.ObjetosSim
partial void OnEstadoChanged(bool value)
{
if (value)
ColorButton_oculto = Colors.LightGreen;
Color_Pressed = Colors.LightGreen;
else
ColorButton_oculto = Color;
Color_Pressed = Colors.Gray;
if (!Tipo_NC)
EscribirBitTag(Tag, value);
else
@ -69,6 +75,9 @@ namespace CtrEditor.ObjetosSim
[ObservableProperty]
public string tag;
[ObservableProperty]
public string tag_Luz;
public void ButtonDownCommand()
{
Estado = true;
@ -87,6 +96,7 @@ namespace CtrEditor.ObjetosSim
Color = Colors.LightBlue;
color_Titulo = Colors.Black;
button_Name = "TAG";
Color_Pressed = Colors.Gray;
}
public override void UpdateGeometryStart()
@ -94,8 +104,11 @@ namespace CtrEditor.ObjetosSim
// Se llama antes de la simulacion
}
public override void UpdatePLC(PLCModel plc, int elapsedMilliseconds)
public override void UpdatePLC(PLCViewModel plc, int elapsedMilliseconds)
{
if (LeerBitTag(Tag_Luz))
ColorButton = ObtenerColorMasClaroYSaturado(Color, 0.3, 0.5);
else ColorButton = Color;
}
public override void UpdatePLCPrimerCiclo() {
@ -114,6 +127,7 @@ namespace CtrEditor.ObjetosSim
// El UserControl ya se ha cargado y podemos obtener las coordenadas para
// crear el objeto de simulacion
base.ucLoaded();
ColorButton = Color;
}
public override void ucUnLoaded()
{
@ -177,7 +191,7 @@ namespace CtrEditor.ObjetosSim
}
public void Rotate(float Angle) {
if (Datos is osBoton osBotonData)
osBotonData.Angulo = Angle;
osBotonData.Angulo += Angle;
}
public void Highlight(bool State) { }
public int ZIndex()

View File

@ -1,5 +1,5 @@

using CtrEditor.Siemens;
using LibS7Adv;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
@ -139,7 +139,7 @@ namespace CtrEditor.ObjetosSim
// Se llama antes de la simulacion
}
public override void UpdatePLC(PLCModel plc, int elapsedMilliseconds)
public override void UpdatePLC(PLCViewModel plc, int elapsedMilliseconds)
{
if (Motor != null)
{

View File

@ -9,12 +9,13 @@
<UserControl.DataContext>
<vm:osPhotocell Color="#FFCA1C1C"/>
<vm:osPhotocell Color="#FFCA1C1C" Ancho="0.8" Nombre="PTH" Alto="0.04" />
</UserControl.DataContext>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition
Width="{Binding Alto, Converter={StaticResource MeterToPixelConverter}, ConverterParameter=5}" />
<!-- Columna para el Label -->
<ColumnDefinition Width="Auto"/>
<!-- Columna para la Image -->
@ -33,9 +34,9 @@
</Viewbox>
<Image Source="/Icons/fotocelula.png"
Width="{Binding Ancho, Converter={StaticResource MeterToPixelConverter}, ConverterParameter=0.1}"
Width="{Binding Alto, Converter={StaticResource MeterToPixelConverter}, ConverterParameter=2}"
Height="{Binding Alto, Converter={StaticResource MeterToPixelConverter}, ConverterParameter=2}"
VerticalAlignment="Center" HorizontalAlignment="Left" Margin="0,0,0,0" Grid.Column="1"/>
VerticalAlignment="Center" HorizontalAlignment="Left" Margin="2,2,2,2" Grid.Column="1"/>
<Rectangle x:Name="Photocell" Grid.Column="2" Width="{Binding Ancho, Converter={StaticResource MeterToPixelConverter}, ConverterParameter=0.9}"
Height="{Binding Alto, Converter={StaticResource MeterToPixelConverter}}">
@ -43,7 +44,9 @@
<VisualBrush x:Name="MovingPattern" TileMode="Tile" Viewport="0,0,3,3" ViewportUnits="Absolute" Viewbox="0,0,3,3" ViewboxUnits="Absolute">
<VisualBrush.Visual>
<Canvas>
<Ellipse Width="2" Height="2" Fill="{Binding Color}"/>
<Ellipse
Width="1"
Height="1" Fill="{Binding Color}"/>
</Canvas>
</VisualBrush.Visual>
</VisualBrush>

View File

@ -1,6 +1,6 @@

using CtrEditor.Simulacion;
using CtrEditor.Siemens;
using LibS7Adv;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
@ -103,6 +103,11 @@ namespace CtrEditor.ObjetosSim
[ObservableProperty]
public bool tipo_NC;
partial void OnTipo_NCChanged(bool value)
{
OnLuzCortadaChanged(LuzCortada);
}
[ObservableProperty]
public string tagPhotocell_OUT;
@ -176,7 +181,7 @@ namespace CtrEditor.ObjetosSim
OnLuzCortadaChanged(LuzCortada);
}
public override void UpdatePLC(PLCModel plc, int elapsedMilliseconds) {
public override void UpdatePLC(PLCViewModel plc, int elapsedMilliseconds) {
}
public override void ucLoaded()
{
@ -217,9 +222,13 @@ namespace CtrEditor.ObjetosSim
}
public void Resize(float width, float height)
{
if (width == 0) return;
if (Datos is osPhotocell datos)
datos.Ancho = PixelToMeter.Instance.calc.PixelsToMeters(width);
{
datos.Ancho += PixelToMeter.Instance.calc.PixelsToMeters(width);
datos.Alto += PixelToMeter.Instance.calc.PixelsToMeters(height/2);
if (datos.Ancho <= 0) datos.Ancho = 0.1f;
if (datos.Alto <= 0) datos.Alto = 0.1f;
}
}
public void Move(float LeftPixels, float TopPixels)
{
@ -233,7 +242,7 @@ namespace CtrEditor.ObjetosSim
{
if (Datos != null)
if (Datos is osPhotocell datos)
datos.Angulo = Angle;
datos.Angulo += Angle;
}
public void Highlight(bool State) { }
public int ZIndex()

View File

@ -1,6 +1,6 @@
using CommunityToolkit.Mvvm.ComponentModel;
using CtrEditor.Siemens;
using LibS7Adv;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
@ -55,7 +55,7 @@ namespace CtrEditor.ObjetosSim
Min_OUT_Scaled = 0;
}
public override void UpdatePLC(PLCModel plc, int elapsedMilliseconds)
public override void UpdatePLC(PLCViewModel plc, int elapsedMilliseconds)
{
}
@ -97,8 +97,8 @@ namespace CtrEditor.ObjetosSim
{
if (Datos is osSensTemperatura datos)
{
datos.Ancho = PixelToMeter.Instance.calc.PixelsToMeters(width);
datos.Alto = PixelToMeter.Instance.calc.PixelsToMeters(width);
datos.Ancho += PixelToMeter.Instance.calc.PixelsToMeters(width);
datos.Alto += PixelToMeter.Instance.calc.PixelsToMeters(width);
}
}
public void Move(float LeftPixels, float TopPixels)
@ -113,7 +113,7 @@ namespace CtrEditor.ObjetosSim
{
if (Datos != null)
if (Datos is osSensTemperatura datos)
datos.Angulo = Angle;
datos.Angulo += Angle;
}
public void Highlight(bool State) { }
public int ZIndex()

View File

@ -1,5 +1,5 @@

using CtrEditor.Siemens;
using LibS7Adv;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
@ -74,7 +74,7 @@ namespace CtrEditor.ObjetosSim
// Se llama antes de la simulacion
}
public override void UpdatePLC(PLCModel plc, int elapsedMilliseconds)
public override void UpdatePLC(PLCViewModel plc, int elapsedMilliseconds)
{
}

View File

@ -11,6 +11,15 @@
<UserControl.DataContext>
<vm:osBoolTag/>
</UserControl.DataContext>
<Canvas RenderTransformOrigin="0.5,0.5">
<Canvas.RenderTransform>
<TransformGroup>
<ScaleTransform />
<SkewTransform />
<RotateTransform Angle="{Binding Angulo}" />
<TranslateTransform />
</TransformGroup>
</Canvas.RenderTransform>
<Grid Margin="10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
@ -25,8 +34,10 @@
Height="40"
VerticalAlignment="Top"
HorizontalAlignment="Left"
Background="Gray"/>
Background="{Binding Color, Converter={StaticResource ColorToBrushConverter}}"/>
<Label Content="{Binding Descripcion}" Grid.Column="1" VerticalAlignment="Center" Background="{Binding Color}" />
<CheckBox Grid.Column="2" VerticalAlignment="Center" IsChecked="{Binding Estado}" />
<CheckBox Grid.Column="2" VerticalAlignment="Center" IsChecked="{Binding Estado}"
Background="{Binding Color_oculto}" />
</Grid>
</Canvas>
</UserControl>

View File

@ -1,5 +1,5 @@

using CtrEditor.Siemens;
using LibS7Adv;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
@ -32,6 +32,9 @@ namespace CtrEditor.ObjetosSim
[ObservableProperty]
private Brush color_oculto;
[ObservableProperty]
Color color;
[ObservableProperty]
public bool estado;
@ -44,6 +47,9 @@ namespace CtrEditor.ObjetosSim
Color_oculto = Brushes.Transparent;
}
[ObservableProperty]
public float angulo;
[ObservableProperty]
public float tamano;
[ObservableProperty]
@ -58,6 +64,7 @@ namespace CtrEditor.ObjetosSim
Tamano = 0.30f;
tag = "%M50.0";
Descripcion = "Nombre del Tag";
Color = Colors.LightBlue;
}
public override void UpdatePLCPrimerCiclo()
@ -102,7 +109,11 @@ namespace CtrEditor.ObjetosSim
Datos.Top = PixelToMeter.Instance.calc.PixelsToMeters(TopPixels);
}
}
public void Rotate(float Angle) { }
public void Rotate(float Angle)
{
if (Datos is osBoolTag osBoolData)
osBoolData.Angulo += Angle;
}
public void Highlight(bool State) { }
public int ZIndex()
{

View File

@ -1,6 +1,6 @@
using CommunityToolkit.Mvvm.ComponentModel;
using CtrEditor.Siemens;
using LibS7Adv;
using System.Windows;
using System.Windows.Controls;

View File

@ -4,7 +4,7 @@ using System.Windows.Controls;
using System.Windows.Media;
using CommunityToolkit.Mvvm.ComponentModel;
using System.Windows.Shapes;
using CtrEditor.Siemens;
using LibS7Adv;
using System.Runtime.Intrinsics;
namespace CtrEditor.ObjetosSim
@ -112,7 +112,7 @@ namespace CtrEditor.ObjetosSim
{
// Escribimos el valor actual al iniciar la conexion
}
public override void UpdatePLC(PLCModel plc, int elapsedMilliseconds)
public override void UpdatePLC(PLCViewModel plc, int elapsedMilliseconds)
{
float v1, v2, v3;
@ -280,8 +280,8 @@ namespace CtrEditor.ObjetosSim
public void Resize(float width, float height) {
if (Datos is osTrace3 datos)
{
datos.Ancho = PixelToMeter.Instance.calc.PixelsToMeters(width);
datos.Alto = PixelToMeter.Instance.calc.PixelsToMeters(height);
datos.Ancho += PixelToMeter.Instance.calc.PixelsToMeters(width);
datos.Alto += PixelToMeter.Instance.calc.PixelsToMeters(height);
}
}
public void Move(float LeftPixels, float TopPixels)

View File

@ -1,5 +1,5 @@

using CtrEditor.Siemens;
using LibS7Adv;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
@ -87,7 +87,7 @@ namespace CtrEditor.ObjetosSim
stopwatch.Start();
}
public override void UpdatePLC(PLCModel plc, int elapsedMilliseconds)
public override void UpdatePLC(PLCViewModel plc, int elapsedMilliseconds)
{
if (Tag_serie != null && Tag_serie.Length > 0) {
var value = LeerBitTag(Tag_serie) == false ? 0 : 1;
@ -145,8 +145,8 @@ namespace CtrEditor.ObjetosSim
public void Resize(float width, float height) {
if (Datos is osTraceSimple datos)
{
datos.Ancho = PixelToMeter.Instance.calc.PixelsToMeters(width);
datos.Alto = PixelToMeter.Instance.calc.PixelsToMeters(height);
datos.Ancho += PixelToMeter.Instance.calc.PixelsToMeters(width);
datos.Alto += PixelToMeter.Instance.calc.PixelsToMeters(height);
}
}
public void Move(float LeftPixels, float TopPixels)

View File

@ -1,7 +1,7 @@

using System.Text.Json.Serialization;
using System.Windows;
using CtrEditor.Siemens;
using LibS7Adv;
using CtrEditor.Simulacion;
using System.Windows.Media;
using nkast.Aether.Physics2D.Common;
@ -79,6 +79,13 @@ namespace CtrEditor.ObjetosSim
[property: Category("Layout:")]
private float left;
public void CheckData()
{
if (Id is null)
Id = new UniqueId().ObtenerNuevaID();
}
partial void OnLeftChanged(float value)
{
CanvasSetLeftinMeter(value);
@ -254,6 +261,21 @@ namespace CtrEditor.ObjetosSim
return "";
}
// Método para obtener un color más claro y saturado
public static Color ObtenerColorMasClaroYSaturado(Color colorOriginal, double incrementoL, double incrementoS)
{
return ColorUtils.ObtenerColorMasClaroYSaturado(colorOriginal, incrementoL, incrementoS);
}
// Método para obtener un color más claro
public Color ObtenerColorMasClaro(Color colorOriginal, double incremento)
{
incremento = Math.Clamp(incremento, 0, 1); // Asegurarse de que el incremento esté entre 0 y 1
byte r = (byte)(colorOriginal.R + (255 - colorOriginal.R) * incremento);
byte g = (byte)(colorOriginal.G + (255 - colorOriginal.G) * incremento);
byte b = (byte)(colorOriginal.B + (255 - colorOriginal.B) * incremento);
return Color.FromArgb(colorOriginal.A, r, g, b);
}
// All Pages Objects
[NotifyPropertyChangedFor(nameof(Show_On_This_Page))]
@ -384,7 +406,7 @@ namespace CtrEditor.ObjetosSim
/// Inicializado en el metodo SetPLC
/// </summary>
[JsonIgnore]
protected PLCModel? _plc = null;
protected PLCViewModel? _plc = null;
/// <summary>
/// Se llama luego de cada Step. Esto permite actualziar las posiciones graficas de cada objeto que se esta dibujando
@ -417,7 +439,7 @@ namespace CtrEditor.ObjetosSim
/// </summary>
/// <param name="plc"></param>
/// <param name="elapsedMilliseconds"></param>
public virtual void UpdatePLC(PLCModel plc, int elapsedMilliseconds) { }
public virtual void UpdatePLC(PLCViewModel plc, int elapsedMilliseconds) { }
/// <summary>
/// El UserControl ya se ha cargado y podemos obtener las coordenadas para
@ -479,7 +501,7 @@ namespace CtrEditor.ObjetosSim
/// Se llama una unica vez al conectar con el PLC.
/// </summary>
/// <param name="plc"></param>
public void SetPLC(PLCModel plc)
public void SetPLC(PLCViewModel plc)
{
_plc = plc;
UpdatePLCPrimerCiclo();
@ -576,7 +598,7 @@ namespace CtrEditor.ObjetosSim
if (_plc == null) return;
if (!string.IsNullOrEmpty(Tag))
if (_plc != null)
_plc.EscribirTagBool(Tag, Value);
_plc.EscribirBool(Tag, Value);
}
public void EscribirWordTagScaled(string Tag, float Value, float IN_scale_Min, float IN_scale_Max, float OUT_scale_Min, float OUT_scale_Max)
@ -992,4 +1014,83 @@ namespace CtrEditor.ObjetosSim
public class HiddenAttribute : Attribute
{
}
public class ColorUtils
{
// Convertir RGB a HSL
public static void RgbToHsl(Color color, out double h, out double s, out double l)
{
double r = color.R / 255.0;
double g = color.G / 255.0;
double b = color.B / 255.0;
double max = Math.Max(r, Math.Max(g, b));
double min = Math.Min(r, Math.Min(g, b));
h = s = l = (max + min) / 2.0;
if (max == min)
{
h = s = 0.0; // Gris
}
else
{
double d = max - min;
s = l > 0.5 ? d / (2.0 - max - min) : d / (max + min);
if (max == r)
h = (g - b) / d + (g < b ? 6.0 : 0.0);
else if (max == g)
h = (b - r) / d + 2.0;
else
h = (r - g) / d + 4.0;
h /= 6.0;
}
}
// Convertir HSL a RGB
public static Color HslToRgb(double h, double s, double l)
{
double r, g, b;
if (s == 0.0)
{
r = g = b = l; // Gris
}
else
{
Func<double, double, double, double> hue2rgb = (p, q, t) =>
{
if (t < 0.0) t += 1.0;
if (t > 1.0) t -= 1.0;
if (t < 1.0 / 6.0) return p + (q - p) * 6.0 * t;
if (t < 1.0 / 2.0) return q;
if (t < 2.0 / 3.0) return p + (q - p) * (2.0 / 3.0 - t) * 6.0;
return p;
};
double q = l < 0.5 ? l * (1.0 + s) : l + s - l * s;
double p = 2.0 * l - q;
r = hue2rgb(p, q, h + 1.0 / 3.0);
g = hue2rgb(p, q, h);
b = hue2rgb(p, q, h - 1.0 / 3.0);
}
return Color.FromArgb(255, (byte)(r * 255.0), (byte)(g * 255.0), (byte)(b * 255.0));
}
// Método para obtener un color más claro y saturado
public static Color ObtenerColorMasClaroYSaturado(Color colorOriginal, double incrementoL, double incrementoS)
{
RgbToHsl(colorOriginal, out double h, out double s, out double l);
l = Math.Clamp(l + incrementoL, 0.0, 1.0);
s = Math.Clamp(s + incrementoS, 0.0, 1.0);
return HslToRgb(h, s, l);
}
}
}

View File

@ -4,7 +4,7 @@ using System.Windows.Media.Animation;
using System.Windows.Media;
using CommunityToolkit.Mvvm.ComponentModel;
using CtrEditor.Siemens;
using LibS7Adv;
using CtrEditor.Simulacion;
using System.Windows.Input;
@ -115,7 +115,7 @@ namespace CtrEditor.ObjetosSim
ActualizarGeometrias();
}
public override void UpdatePLC(PLCModel plc, int elapsedMilliseconds)
public override void UpdatePLC(PLCViewModel plc, int elapsedMilliseconds)
{
if (_osMotor != null)
{
@ -168,7 +168,7 @@ namespace CtrEditor.ObjetosSim
public void Resize(float width, float height)
{
if (Datos is osBasicExample datos)
datos.Ancho = PixelToMeter.Instance.calc.PixelsToMeters(width);
datos.Ancho += PixelToMeter.Instance.calc.PixelsToMeters(width);
}
public void Move(float LeftPixels, float TopPixels)
{
@ -182,7 +182,7 @@ namespace CtrEditor.ObjetosSim
{
if (Datos != null)
if (Datos is osBasicExample datos)
datos.Angulo = Angle;
datos.Angulo += Angle;
}
public void Highlight(bool State) { }
public int ZIndex()

View File

@ -1,42 +0,0 @@
<UserControl x:Class="CtrEditor.Siemens.PLCControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:CtrEditor.Siemens">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="2*"/>
</Grid.ColumnDefinitions>
<Label Content="IP:" Grid.Row="0" Grid.Column="0" Margin="1" VerticalAlignment="Center"/>
<TextBox Text="{Binding IP, UpdateSourceTrigger=PropertyChanged}"
Grid.Row="0" Grid.Column="1" Margin="1" VerticalAlignment="Center"/>
<Label Content="Name:" Grid.Row="1" Grid.Column="0" Margin="1" VerticalAlignment="Center"/>
<TextBox Text="{Binding Name, UpdateSourceTrigger=PropertyChanged}"
Grid.Row="1" Grid.Column="1" Margin="1" VerticalAlignment="Center"/>
<Button Content="Connect" Command="{Binding ConnectCommand}"
Grid.Row="2" Grid.Column="0" Margin="1" VerticalAlignment="Center"/>
<Button Content="Disconnect" Command="{Binding DisconnectCommand}"
Grid.Row="2" Grid.Column="1" Margin="1" VerticalAlignment="Center"/>
<Label Content="CPU cycle:" Grid.Row="3" Grid.Column="0" Margin="1" VerticalAlignment="Center"/>
<Label Content="{Binding CpuTime}" Grid.Row="3" Grid.Column="1" Margin="1" VerticalAlignment="Center"/>
<Label Grid.Row="4" Grid.Column="0" Margin="1" VerticalAlignment="Center">
Last Error:
</Label>
<Label Grid.Row="4" Grid.Column="1" Margin="1" VerticalAlignment="Center" HorizontalAlignment="Stretch">
<TextBlock Text="{Binding LastError}" TextWrapping="Wrap" Padding="3"/>
</Label>
</Grid>
</UserControl>

View File

@ -1,315 +0,0 @@
using Siemens.Simatic.Simulation.Runtime;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Text.Json.Serialization;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Threading;
namespace CtrEditor.Siemens
{
/// <summary>
/// Interaction logic for PLCControl.xaml
/// </summary>
public class PLCViewModel : INotifyPropertyChanged
{
public readonly PLCModel PLCInterface;
private readonly DispatcherTimer _timer;
private string _cpuTime;
private string _connectionStatus = "offline";
private string _ip = "10.1.30.11";
private string _name = "PLC";
private string lastError;
public bool IsConnected { get; private set; }
public event PropertyChangedEventHandler PropertyChanged;
public event EventHandler RefreshEvent;
public PLCViewModel()
{
IsConnected = false;
PLCInterface = new PLCModel();
_timer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(30) };
_timer.Tick += (s, e) => Refresh();
ConnectCommand = new RelayCommand(Connect, () => true);
DisconnectCommand = new RelayCommand(Disconnect, () => true);
}
public string IP
{
get => _ip;
set
{
_ip = value;
OnPropertyChanged();
}
}
public string Name
{
get => _name;
set
{
_name = value;
OnPropertyChanged();
}
}
public string CpuTime
{
get => _cpuTime;
set
{
_cpuTime = value;
OnPropertyChanged();
}
}
public string ConnectionStatus
{
get => _connectionStatus;
set
{
_connectionStatus = value;
OnPropertyChanged();
}
}
[JsonIgnore]
public ICommand ConnectCommand { get; }
public ICommand DisconnectCommand { get; }
public string LastError
{
get => lastError;
set
{
lastError = value;
OnPropertyChanged();
}
}
public void Connect()
{
try
{
// Implementa la conexión utilizando PLCModel
PLCInterface.Instance = SimulationRuntimeManager.CreateInterface(Name);
PLCInterface.Instance.OnSoftwareConfigurationChanged += Instance_OnSoftwareConfigurationChanged;
//_plcModel.Instance.CommunicationInterface = ECommunicationInterface.Softbus;
if (PLCInterface.Instance != null)
{
PLCInterface.UpdateTagList();
_timer.Start();
ConnectionStatus = "connected";
IsConnected = true;
}
}
catch (Exception ex)
{
LastError = ex.Message;
ConnectionStatus = "offline";
}
}
private void Instance_OnSoftwareConfigurationChanged(IInstance instance, SOnSoftwareConfigChangedParameter event_param)
{
PLCInterface.UpdateTagList();
}
public void Disconnect()
{
IsConnected = false;
_timer.Stop();
ConnectionStatus = "offline";
PLCInterface.Instance = null;
}
private void Refresh()
{
if (PLCInterface.Instance != null)
{
CpuTime = PLCInterface.LeerTagInt16("\"DB HMI\".CPU_Scan_Time")?.ToString() ?? "N/A";
LastError = PLCInterface.LastError;
// Disparar el evento RefreshEvent
RefreshEvent?.Invoke(this, EventArgs.Empty);
}
}
private void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
public enum SiemensAbsoluteAreaType
{
IO,
M,
DB,
Tag
}
public enum SiemensAbsoluteTagType
{
Byte,
Char,
Int,
DInt,
Word,
DWord,
Real,
Date,
Time,
Time_Of_Day,
S5Time,
Bool,
String,
WString,
LReal,
UDInt,
USInt,
UInt,
ULInt,
LWord,
LInt,
Date_And_Time,
DTL
}
public class TagAddress
{
SiemensAbsoluteAreaType areaType;
SiemensAbsoluteTagType tagType;
int DB;
int word_offset;
int bit;
}
public class PLCModel
{
public IInstance Instance { get; set; }
public bool IsConfigured { get; set; }
public string LastError { get; set; }
public void UpdateTagList()
{
IsConfigured = false;
try
{
Instance?.UpdateTagList(ETagListDetails.IO | ETagListDetails.DB | ETagListDetails.M, true); // ETagListDetails.IO | ETagListDetails.DB
IsConfigured = true;
}
catch (Exception ex)
{
LastError = ex.Message;
}
}
public bool LeerSalidaBool(byte pByte, int pBit)
{
try
{
return Instance?.OutputArea.ReadBit(pByte, (byte)pBit) ?? false;
}
catch (Exception ex)
{
LastError = ex.Message;
return false;
}
}
public void EscribirInputBool(byte pByte, int pBit, bool pValue)
{
try
{
Instance?.InputArea.WriteBit(pByte, (byte)pBit, pValue);
}
catch (Exception ex)
{
LastError = ex.Message;
}
}
public void EscribirTag(string pTag, SDataValue Value)
{
try
{
Instance?.Write(pTag, Value);
}
catch (Exception ex)
{
LastError = pTag + ":" + ex.Message;
}
}
public SDataValue LeerTag(string pTag)
{
try
{
return Instance.Read(pTag);
}
catch (Exception ex)
{
LastError = pTag + ":" + ex.Message;
return new SDataValue();
}
}
public void EscribirTagBool(string pTag, bool pValue)
{
try
{
Instance?.WriteBool(pTag, pValue);
}
catch (Exception ex)
{
LastError = pTag + ":" + ex.Message;
}
}
public void EscribirTagInt16(string pTag, int pValue)
{
try
{
Instance?.WriteInt16(pTag, (short)pValue);
}
catch (Exception ex)
{
LastError = pTag + ":" + ex.Message;
}
}
public bool LeerTagBool(string pTag)
{
try
{
return Instance?.ReadBool(pTag) ?? false;
}
catch (Exception ex)
{
LastError = pTag + ":" + ex.Message;
return false;
}
}
public int? LeerTagInt16(string pTag)
{
try
{
return Instance?.ReadInt16(pTag);
}
catch (Exception ex)
{
LastError = pTag + ":" + ex.Message;
return 0;
}
}
}
public partial class PLCControl : UserControl
{
public PLCControl()
{
InitializeComponent();
}
}
}

View File

@ -1,52 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Siemens.Simatic;
using Siemens.Simatic.Simulation.Runtime;
namespace CtrEditor.Siemens
{
internal class PLCSim
{
SIPSuite4 plcIP;
}
public class PLCConnector
{
// Propiedades
public IInstance Instance { get; set; }
private bool IsConfigured { get; set; } = false;
private SIPSuite4 InstanceIP;
// Constructor
public PLCConnector(string instanceName, string pIP4)
{
InstanceIP = new SIPSuite4(pIP4, "255.255.255.0", "0.0.0.0");
Instance = SimulationRuntimeManager.CreateInterface(instanceName);
}
// Métodos Públicos
public void PowerOnPLCInstance()
{
Instance.PowerOn(60000);
Instance.SetIPSuite(0, InstanceIP, true);
}
public void PowerOffPLCInstance()
{
Instance.PowerOff(6000);
}
public void RunPLCInstance()
{
Instance.Run(6000);
}
public void StopPLCInstance()
{
Instance.Stop(6000);
}
}
}

View File

@ -25,6 +25,11 @@ namespace CtrEditor.Simulacion
_world.Remove(Body);
}
}
public static float Min(float Value, float Min = 0.01f)
{
return Value < Min ? Min : Value;
}
public static float GradosARadianes(float grados)
{
return (float)(grados * (Math.PI / 180));
@ -161,6 +166,8 @@ namespace CtrEditor.Simulacion
public void SetDiameter(float diameter)
{
if (diameter <= 0)
diameter = 0.01f;
_radius = diameter / 2;
Create(Body.Position); // Recrear el círculo con el nuevo tamaño
}
@ -248,11 +255,11 @@ namespace CtrEditor.Simulacion
public simBarrera(World world, List<Action> deferredActions, float width, float height, Vector2 position, float angle = 0, bool detectectNeck = false)
{
_world = world;
_height = height;
_height = Min(height);
DetectNeck = detectectNeck;
_deferredActions = deferredActions;
ListSimBotellaContact = new List<simBotella>();
Create(width, height, position, angle);
Create(Min(width), _height, position, angle);
}
public float Angle
@ -270,16 +277,16 @@ namespace CtrEditor.Simulacion
{
Body.Remove(Body.FixtureList[0]);
var newShape = new PolygonShape(PolygonTools.CreateRectangle(width / 2, height / 2), 1f);
var newShape = new PolygonShape(PolygonTools.CreateRectangle(Min(width) / 2, Min(height) / 2), 1f);
Body.CreateFixture(newShape);
}
public void Create(float width, float height, Vector2 position, float angle = 0, bool detectectNeck = false)
{
RemoverBody();
_height = height;
_height = Min(height);
DetectNeck = detectectNeck;
Body = _world.CreateRectangle( width, height, 1f, position);
Body = _world.CreateRectangle( Min(width), _height, 1f, position);
Body.FixtureList[0].IsSensor = true;
Body.BodyType = BodyType.Static;
Body.Rotation = GradosARadianes(angle);

29
dataDebug.cs Normal file
View File

@ -0,0 +1,29 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using CommunityToolkit.Mvvm.ComponentModel;
namespace CtrEditor
{
partial class dataDebug : ObservableObject
{
[ObservableProperty]
private Point transformedBoundingBoxCenter;
[ObservableProperty]
private Point currentPosition;
[ObservableProperty]
private float lastAngle;
[ObservableProperty]
private float angle;
[ObservableProperty]
string note;
}
}

17
wDebug.xaml Normal file
View File

@ -0,0 +1,17 @@
<Window x:Class="CtrEditor.wDebug"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:CtrEditor"
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
mc:Ignorable="d"
Title="wDebug" Height="450" Width="400">
<Grid>
<xctk:PropertyGrid Grid.Row="4" Margin="5" x:Name="PanelPropiedades" AutoGenerateProperties="True"
ShowDescriptionByTooltip="True" SelectedObject="{Binding Data}">
</xctk:PropertyGrid>
</Grid>
</Window>

25
wDebug.xaml.cs Normal file
View File

@ -0,0 +1,25 @@
using System.Windows;
using CommunityToolkit.Mvvm.ComponentModel;
namespace CtrEditor
{
/// <summary>
/// Interaction logic for wDebug.xaml
/// </summary>
[ObservableObject]
public partial class wDebug : Window
{
[ObservableProperty]
Object data;
public wDebug()
{
InitializeComponent();
this.DataContext = this; // Establecer el DataContext de la ventana en la misma instancia
}
}
}