Creado BuscarCoincidencias, implementando logica
This commit is contained in:
parent
84725cc8d6
commit
0305ae2506
3
App.xaml
3
App.xaml
|
@ -2,6 +2,7 @@
|
|||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="clr-namespace:CtrEditor"
|
||||
xmlns:os="clr-namespace:CtrEditor.ObjetosSim.Extraccion_Datos"
|
||||
StartupUri="MainWindow.xaml">
|
||||
|
||||
<Application.Resources>
|
||||
|
@ -17,6 +18,8 @@
|
|||
<local:SumConverter x:Key="SumConverter" />
|
||||
<local:ColorToBrushConverter x:Key="ColorToBrushConverter"/>
|
||||
<local:StringToBrushConverter x:Key="StringToBrushConverter"/>
|
||||
<local:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter" />
|
||||
<local:SubclassFilterConverter x:Key="SubclassFilterConverter" TargetType="{x:Type os:osBuscarCoincidencias}" />
|
||||
</Application.Resources>
|
||||
</Application>
|
||||
|
||||
|
|
|
@ -66,6 +66,9 @@
|
|||
<ItemGroup>
|
||||
<PackageReference Include="Aether.Physics2D" Version="2.1.0" />
|
||||
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.2" />
|
||||
<PackageReference Include="Emgu.CV" Version="4.9.0.5494" />
|
||||
<PackageReference Include="Emgu.CV.runtime.windows" Version="4.9.0.5494" />
|
||||
<PackageReference Include="Emgu.CV.UI" Version="4.9.0.5494" />
|
||||
<PackageReference Include="Extended.Wpf.Toolkit" Version="4.6.0" />
|
||||
<PackageReference Include="LiveChartsCore.SkiaSharpView.WPF" Version="2.0.0-rc2" />
|
||||
<PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.122" />
|
||||
|
|
|
@ -178,8 +178,7 @@
|
|||
ResizeDirection="Rows" VerticalAlignment="Center" />
|
||||
|
||||
<!-- PanelEdicion -->
|
||||
<xctk:PropertyGrid Grid.Row="2" Margin="5" x:Name="PanelEdicion" AutoGenerateProperties="False"
|
||||
SelectedObject="{Binding}">
|
||||
<xctk:PropertyGrid Grid.Row="2" Margin="5" x:Name="PanelEdicion" AutoGenerateProperties="False">
|
||||
<xctk:PropertyGrid.EditorDefinitions>
|
||||
|
||||
<!-- String -->
|
||||
|
@ -231,6 +230,21 @@
|
|||
</xctk:EditorTemplateDefinition.EditingTemplate>
|
||||
</xctk:EditorTemplateDefinition>
|
||||
|
||||
<!-- osBase -->
|
||||
<xctk:EditorTemplateDefinition>
|
||||
<xctk:EditorTemplateDefinition.TargetProperties>
|
||||
<xctk:TargetPropertyType Type="{x:Type ObjetosSim:osBase}" />
|
||||
</xctk:EditorTemplateDefinition.TargetProperties>
|
||||
<xctk:EditorTemplateDefinition.EditingTemplate>
|
||||
<DataTemplate>
|
||||
<ComboBox ItemsSource="{Binding DataContext.ObjetosSimulables,
|
||||
RelativeSource={RelativeSource AncestorType=Window},
|
||||
Converter={StaticResource SubclassFilterConverter}}"
|
||||
SelectedItem="{Binding Value}" DisplayMemberPath="Nombre" />
|
||||
</DataTemplate>
|
||||
</xctk:EditorTemplateDefinition.EditingTemplate>
|
||||
</xctk:EditorTemplateDefinition>
|
||||
|
||||
</xctk:PropertyGrid.EditorDefinitions>
|
||||
</xctk:PropertyGrid>
|
||||
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
<UserControl x:Class="CtrEditor.ObjetosSim.Extraccion_Datos.ucBuscarCoincidencias"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
|
||||
xmlns:vm="clr-namespace:CtrEditor.ObjetosSim.Extraccion_Datos" mc:Ignorable="d"
|
||||
Visibility="{Binding Show_on_this_page, Converter={StaticResource BoolToVisibilityConverter}}">
|
||||
|
||||
<UserControl.DataContext>
|
||||
<vm:osBuscarCoincidencias />
|
||||
</UserControl.DataContext>
|
||||
|
||||
<Canvas>
|
||||
<Rectangle x:Name="Area" Width="{Binding Ancho, Converter={StaticResource MeterToPixelConverter}}"
|
||||
Height="{Binding Alto, Converter={StaticResource MeterToPixelConverter}}"
|
||||
Opacity="{Binding Opacity_oculto}" Fill="Yellow" Stroke="Black">
|
||||
<Rectangle.RenderTransform>
|
||||
<RotateTransform Angle="{Binding Angulo}" />
|
||||
</Rectangle.RenderTransform>
|
||||
</Rectangle>
|
||||
</Canvas>
|
||||
</UserControl>
|
|
@ -0,0 +1,354 @@
|
|||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Media;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CtrEditor.Simulacion;
|
||||
using System.IO;
|
||||
using System.Windows.Media.Imaging;
|
||||
using Tesseract;
|
||||
using Emgu.CV.CvEnum;
|
||||
using Emgu.CV.Structure;
|
||||
using Emgu.CV;
|
||||
using System.Drawing;
|
||||
using Image = System.Windows.Controls.Image;
|
||||
using Point = System.Drawing.Point;
|
||||
using Rectangle = System.Windows.Shapes.Rectangle;
|
||||
using Size = System.Drawing.Size;
|
||||
using Ookii.Dialogs.Wpf;
|
||||
|
||||
|
||||
namespace CtrEditor.ObjetosSim.Extraccion_Datos
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for ucBuscarCoincidencias.xaml
|
||||
/// </summary>
|
||||
///
|
||||
|
||||
public partial class osBuscarCoincidencias : osBase, IosBase
|
||||
{
|
||||
private osBase _osMotor = null;
|
||||
|
||||
private simTransporte SimGeometria;
|
||||
|
||||
public static string NombreClase()
|
||||
{
|
||||
return "Search Templates";
|
||||
}
|
||||
private string nombre = NombreClase();
|
||||
public override string Nombre
|
||||
{
|
||||
get => nombre;
|
||||
set => SetProperty(ref nombre, value);
|
||||
}
|
||||
|
||||
[ObservableProperty]
|
||||
bool search_templates;
|
||||
|
||||
partial void OnSearch_templatesChanged(bool oldValue, bool newValue)
|
||||
{
|
||||
if (Search_templates)
|
||||
BuscarCoincidencias();
|
||||
Search_templates = false;
|
||||
}
|
||||
|
||||
public override void TopChanged(float value)
|
||||
{
|
||||
base.TopChanged(value);
|
||||
Search_templates = false;
|
||||
}
|
||||
|
||||
public override void LeftChanged(float value)
|
||||
{
|
||||
base.LeftChanged(value);
|
||||
Search_templates = false;
|
||||
}
|
||||
|
||||
|
||||
[ObservableProperty]
|
||||
public float ancho;
|
||||
|
||||
partial void OnAnchoChanged(float value)
|
||||
{
|
||||
Search_templates = false;
|
||||
}
|
||||
|
||||
[ObservableProperty]
|
||||
public float alto;
|
||||
|
||||
partial void OnAltoChanged(float value)
|
||||
{
|
||||
Search_templates = false;
|
||||
}
|
||||
|
||||
public override void OnTimerAfterMovement()
|
||||
{
|
||||
}
|
||||
|
||||
[ObservableProperty]
|
||||
public int n_Repeat_X;
|
||||
|
||||
[ObservableProperty]
|
||||
public int n_Repeat_Y;
|
||||
|
||||
[ObservableProperty]
|
||||
public float offset_Repeat_X;
|
||||
|
||||
[ObservableProperty]
|
||||
public float offset_Repeat_Y;
|
||||
|
||||
[ObservableProperty]
|
||||
public float angulo;
|
||||
|
||||
[ObservableProperty]
|
||||
string tag_extract;
|
||||
|
||||
[ObservableProperty]
|
||||
string clase;
|
||||
|
||||
[ObservableProperty]
|
||||
string tag_name;
|
||||
|
||||
[ObservableProperty]
|
||||
float opacity_oculto;
|
||||
|
||||
[ObservableProperty]
|
||||
bool show_debug_ocr;
|
||||
|
||||
[ObservableProperty]
|
||||
float threshold;
|
||||
|
||||
public osBuscarCoincidencias()
|
||||
{
|
||||
Ancho = 1;
|
||||
Alto = 1;
|
||||
Angulo = 0;
|
||||
Opacity_oculto = 0.1f;
|
||||
}
|
||||
|
||||
private void ShowPreviewWindow(Stream imageStream)
|
||||
{
|
||||
// Create a new window for preview
|
||||
Window previewWindow = new Window
|
||||
{
|
||||
Title = "Preview Captured Image",
|
||||
Width = 500,
|
||||
Height = 500,
|
||||
Content = new Image
|
||||
{
|
||||
Source = BitmapFrame.Create(imageStream, BitmapCreateOptions.None, BitmapCacheOption.OnLoad),
|
||||
Stretch = Stretch.Uniform
|
||||
}
|
||||
};
|
||||
|
||||
previewWindow.ShowDialog();
|
||||
}
|
||||
|
||||
private async void BuscarCoincidencias()
|
||||
{
|
||||
var progressDialog = new ProgressDialog
|
||||
{
|
||||
WindowTitle = "Procesando",
|
||||
Text = "Buscando coincidencias...",
|
||||
ShowTimeRemaining = true,
|
||||
ShowCancelButton = false
|
||||
};
|
||||
progressDialog.DoWork += (sender, e) => BuscarCoincidenciasAsync(progressDialog);
|
||||
progressDialog.RunWorkerCompleted += (sender, e) =>
|
||||
{
|
||||
if (e.Error != null)
|
||||
{
|
||||
MessageBox.Show(e.Error.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
}
|
||||
};
|
||||
|
||||
progressDialog.Show();
|
||||
}
|
||||
|
||||
|
||||
private void BuscarCoincidenciasAsync(ProgressDialog progressDialog)
|
||||
{
|
||||
// Reset the Canvas children
|
||||
Application.Current.Dispatcher.Invoke(() =>
|
||||
{
|
||||
var clearShapes = _mainViewModel.MainCanvas.Children.OfType<System.Windows.Shapes.Shape>().Where(s => s.Tag as string == "BuscarCoincidencias").ToList();
|
||||
foreach (var shape in clearShapes)
|
||||
{
|
||||
_mainViewModel.MainCanvas.Children.Remove(shape);
|
||||
}
|
||||
if (_mainViewModel?.MainCanvas.Children[0] is Image imagenDeFondo)
|
||||
{
|
||||
// Asegurarse de que la imagen origen está disponible
|
||||
if (imagenDeFondo.Source is BitmapSource bitmapSource)
|
||||
{
|
||||
progressDialog.ReportProgress(10);
|
||||
// Obtener los DPI de la imagen original
|
||||
float originalDpiX = (float)bitmapSource.DpiX;
|
||||
float originalDpiY = (float)bitmapSource.DpiY;
|
||||
|
||||
// Estándar DPI en el que el Canvas renderiza la imagen
|
||||
float canvasDpiX = 96; // WPF usually renders at 96 DPI
|
||||
float canvasDpiY = 96;
|
||||
|
||||
// Calcular el ratio de escala entre el Canvas y la imagen original
|
||||
float scaleFactorX = originalDpiX / canvasDpiX;
|
||||
float scaleFactorY = originalDpiY / canvasDpiY;
|
||||
|
||||
// Ajustar las coordenadas de recorte en función del ratio de escala
|
||||
int x = (int)MeterToPixels(Left * scaleFactorX);
|
||||
int y = (int)MeterToPixels(Top * scaleFactorY);
|
||||
int width = (int)MeterToPixels(Ancho * scaleFactorX);
|
||||
int height = (int)MeterToPixels(Alto * scaleFactorY);
|
||||
|
||||
// Validar y ajustar el tamaño del recorte para que se mantenga dentro de los límites de la imagen
|
||||
if (x < 0) x = 0;
|
||||
if (y < 0) y = 0;
|
||||
if (x + width > bitmapSource.PixelWidth) width = bitmapSource.PixelWidth - x;
|
||||
if (y + height > bitmapSource.PixelHeight) height = bitmapSource.PixelHeight - y;
|
||||
|
||||
// Recortar el área deseada utilizando las coordenadas ajustadas
|
||||
CroppedBitmap croppedBitmap = new CroppedBitmap(bitmapSource, new Int32Rect(x, y, width, height));
|
||||
|
||||
// Convertir CroppedBitmap a Mat directamente
|
||||
Mat templateMat = BitmapSourceToMat(croppedBitmap);
|
||||
|
||||
int scale = 4;
|
||||
|
||||
// Convertir la plantilla a escala de grises y redimensionarla
|
||||
Mat templateGray = new Mat();
|
||||
CvInvoke.CvtColor(templateMat, templateGray, ColorConversion.Bgr2Gray);
|
||||
Mat templateGrayResized = new Mat();
|
||||
CvInvoke.Resize(templateGray, templateGrayResized, new Size(templateGray.Width / scale, templateGray.Height / scale), 0, 0, Inter.Linear);
|
||||
progressDialog.ReportProgress(20);
|
||||
// Cargar la imagen principal completa en un Mat
|
||||
Mat mainImageMat = BitmapSourceToMat(bitmapSource);
|
||||
|
||||
// Convertir la imagen principal a escala de grises y redimensionarla
|
||||
Mat mainImageGray = new Mat();
|
||||
CvInvoke.CvtColor(mainImageMat, mainImageGray, ColorConversion.Bgr2Gray);
|
||||
Mat mainImageGrayResized = new Mat();
|
||||
CvInvoke.Resize(mainImageGray, mainImageGrayResized, new Size(mainImageGray.Width / scale, mainImageGray.Height / scale), 0, 0, Inter.Linear);
|
||||
|
||||
progressDialog.ReportProgress(50);
|
||||
|
||||
// Realizar la coincidencia de plantillas
|
||||
Mat result = new Mat();
|
||||
CvInvoke.MatchTemplate(mainImageGray, templateGray, result, TemplateMatchingType.CcoeffNormed);
|
||||
|
||||
// Establecer un umbral de coincidencia
|
||||
if (Threshold < 0.4)
|
||||
Threshold = 0.4f;
|
||||
double threshold = Threshold;
|
||||
|
||||
int ConteoPositivos = 0;
|
||||
|
||||
// Obtener los puntos que superan el umbral
|
||||
float[] resultArray = result.GetData(false) as float[];
|
||||
if (resultArray != null)
|
||||
{
|
||||
for (int i = 0; i < resultArray.Length; i++)
|
||||
{
|
||||
if (resultArray[i] >= threshold)
|
||||
{
|
||||
int row = i / result.Cols;
|
||||
int col = i % result.Cols;
|
||||
// Crear y agregar el rectángulo al Canvas (ajustando por la escala)
|
||||
|
||||
Rectangle matchRect = new Rectangle
|
||||
{
|
||||
Stroke = new SolidColorBrush(Colors.Red),
|
||||
StrokeThickness = 2,
|
||||
Width = width / scaleFactorX,
|
||||
Height = height / scaleFactorY,
|
||||
Tag = "BuscarCoincidencias"
|
||||
};
|
||||
Canvas.SetLeft(matchRect, col / scaleFactorX);
|
||||
Canvas.SetTop(matchRect, row / scaleFactorY);
|
||||
Canvas.SetZIndex(matchRect, 40);
|
||||
_mainViewModel.MainCanvas.Children.Add(matchRect);
|
||||
ConteoPositivos++;
|
||||
progressDialog.ReportProgress(90);
|
||||
if (ConteoPositivos > 20)
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Método para convertir BitmapSource a Mat
|
||||
private Mat BitmapSourceToMat(BitmapSource bitmapSource)
|
||||
{
|
||||
Bitmap bitmap;
|
||||
using (MemoryStream outStream = new MemoryStream())
|
||||
{
|
||||
BitmapEncoder enc = new BmpBitmapEncoder();
|
||||
enc.Frames.Add(BitmapFrame.Create(bitmapSource));
|
||||
enc.Save(outStream);
|
||||
bitmap = new Bitmap(outStream);
|
||||
}
|
||||
return bitmap.ToMat();
|
||||
}
|
||||
|
||||
public override void ucLoaded()
|
||||
{
|
||||
// El UserControl ya se ha cargado y podemos obtener las coordenadas para
|
||||
// crear el objeto de simulacion
|
||||
base.ucLoaded();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public partial class ucBuscarCoincidencias : UserControl, IDataContainer
|
||||
{
|
||||
public osBase? Datos { get; set; }
|
||||
|
||||
public ucBuscarCoincidencias()
|
||||
{
|
||||
InitializeComponent();
|
||||
this.Loaded += OnLoaded;
|
||||
this.Unloaded += OnUnloaded;
|
||||
}
|
||||
private void OnLoaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Datos?.ucLoaded();
|
||||
}
|
||||
private void OnUnloaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Datos?.ucUnLoaded();
|
||||
}
|
||||
public void Resize(float width, float height)
|
||||
{
|
||||
if (Datos is osBuscarCoincidencias datos)
|
||||
{
|
||||
datos.Ancho = PixelToMeter.Instance.calc.PixelsToMeters(width);
|
||||
datos.Alto = PixelToMeter.Instance.calc.PixelsToMeters(height);
|
||||
}
|
||||
}
|
||||
public void Move(float LeftPixels, float TopPixels)
|
||||
{
|
||||
if (Datos != null)
|
||||
{
|
||||
Datos.Left = PixelToMeter.Instance.calc.PixelsToMeters(LeftPixels);
|
||||
Datos.Top = PixelToMeter.Instance.calc.PixelsToMeters(TopPixels);
|
||||
}
|
||||
}
|
||||
public void Rotate(float Angle)
|
||||
{
|
||||
if (Datos != null)
|
||||
if (Datos is osBuscarCoincidencias datos)
|
||||
datos.Angulo = Angle;
|
||||
}
|
||||
public void Highlight(bool State) { }
|
||||
public int ZIndex()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -5,16 +5,17 @@
|
|||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
|
||||
xmlns:vm="clr-namespace:CtrEditor.ObjetosSim.Extraccion_Datos"
|
||||
mc:Ignorable="d">
|
||||
mc:Ignorable="d"
|
||||
Visibility="{Binding Show_on_this_page, Converter={StaticResource BoolToVisibilityConverter}}">
|
||||
|
||||
<UserControl.DataContext>
|
||||
<vm:osExtraccionTag/>
|
||||
</UserControl.DataContext>
|
||||
|
||||
<Canvas>
|
||||
<Rectangle x:Name="Transporte"
|
||||
<Rectangle x:Name="Area"
|
||||
Width="{Binding Ancho, Converter={StaticResource MeterToPixelConverter}}"
|
||||
Height="{Binding Alto, Converter={StaticResource MeterToPixelConverter}}" Opacity="0.1" Fill="Green"
|
||||
Height="{Binding Alto, Converter={StaticResource MeterToPixelConverter}}" Opacity="{Binding Opacity_oculto}" Fill="Green"
|
||||
Stroke="Black"
|
||||
|
||||
>
|
||||
|
|
|
@ -78,16 +78,7 @@ namespace CtrEditor.ObjetosSim.Extraccion_Datos
|
|||
}
|
||||
|
||||
[ObservableProperty]
|
||||
public int n_Repeat_X;
|
||||
|
||||
[ObservableProperty]
|
||||
public int n_Repeat_Y;
|
||||
|
||||
[ObservableProperty]
|
||||
public float offset_Repeat_X;
|
||||
|
||||
[ObservableProperty]
|
||||
public float offset_Repeat_Y;
|
||||
osBase search_Templates;
|
||||
|
||||
[ObservableProperty]
|
||||
public float angulo;
|
||||
|
@ -101,11 +92,19 @@ namespace CtrEditor.ObjetosSim.Extraccion_Datos
|
|||
[ObservableProperty]
|
||||
string tag_name;
|
||||
|
||||
[ObservableProperty]
|
||||
float opacity_oculto;
|
||||
|
||||
[ObservableProperty]
|
||||
bool show_debug_ocr;
|
||||
|
||||
|
||||
public osExtraccionTag()
|
||||
{
|
||||
Ancho = 1;
|
||||
Alto = 1;
|
||||
Angulo = 0;
|
||||
Opacity_oculto = 0.1f;
|
||||
}
|
||||
|
||||
private void ShowPreviewWindow(Stream imageStream)
|
||||
|
@ -170,7 +169,7 @@ namespace CtrEditor.ObjetosSim.Extraccion_Datos
|
|||
memoryStream.Seek(0, SeekOrigin.Begin);
|
||||
|
||||
// Mostrar la imagen recortada en una ventana de previsualización
|
||||
// ShowPreviewWindow(memoryStream);
|
||||
if (show_debug_ocr) ShowPreviewWindow(memoryStream);
|
||||
|
||||
// Cargar la imagen en Tesseract desde el MemoryStream
|
||||
using (var img = Pix.LoadFromMemory(memoryStream.ToArray()))
|
||||
|
|
|
@ -40,8 +40,8 @@ namespace CtrEditor.ObjetosSim
|
|||
// crear el objeto de simulacion
|
||||
ActualizarLeftTop();
|
||||
|
||||
if (_visualRepresentation is ucConsensGeneric uc)
|
||||
Tags = UserControlFactory.CargarPropiedadesosDatosTags(Consensos, uc.PanelEdicion, null);
|
||||
//if (_visualRepresentation is ucConsensGeneric uc)
|
||||
// Tags = UserControlFactory.CargarPropiedadesosDatosTags(Consensos, uc.PanelEdicion, null);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ using System.Diagnostics;
|
|||
using System.Globalization;
|
||||
using Xceed.Wpf.Toolkit;
|
||||
using Xceed.Wpf.Toolkit.PropertyGrid.Editors;
|
||||
using CtrEditor.ObjetosSim.Extraccion_Datos;
|
||||
|
||||
namespace CtrEditor.ObjetosSim
|
||||
{
|
||||
|
@ -93,7 +94,7 @@ namespace CtrEditor.ObjetosSim
|
|||
var properties = TypeDescriptor.GetProperties(selectedObject)
|
||||
.Cast<PropertyDescriptor>()
|
||||
.Where(prop => !prop.Attributes.OfType<HiddenAttribute>().Any()).OrderBy(prop => prop.Name);
|
||||
|
||||
|
||||
foreach (var property in properties)
|
||||
{
|
||||
var displayNameAttr = property.Attributes.OfType<DisplayNameAttribute>().FirstOrDefault();
|
||||
|
@ -113,7 +114,7 @@ namespace CtrEditor.ObjetosSim
|
|||
propertyDefinition.DisplayName = property.Name.Replace("_", " ");
|
||||
}
|
||||
if (property.PropertyType == typeof(double) || property.PropertyType == typeof(float) || property.PropertyType == typeof(string) || property.PropertyType == typeof(int) ||
|
||||
property.PropertyType == typeof(bool) || property.PropertyType == typeof(Color))
|
||||
property.PropertyType == typeof(bool) || property.PropertyType == typeof(osBase) || property.PropertyType == typeof(Color) )
|
||||
{
|
||||
propertyGrid.PropertyDefinitions.Add(propertyDefinition);
|
||||
}
|
||||
|
@ -123,341 +124,6 @@ namespace CtrEditor.ObjetosSim
|
|||
propertyGrid.SelectedObject = selectedObject;
|
||||
}
|
||||
|
||||
public static void CargarPropiedadesosDatosex(Object selectedObject, StackPanel PanelEdicion, ResourceDictionary Resources)
|
||||
{
|
||||
PanelEdicion.Children.Clear();
|
||||
var properties = selectedObject.GetType().GetProperties().OrderBy(p => p.Name); // Ordenar alfabéticamente
|
||||
|
||||
foreach (var property in properties)
|
||||
{
|
||||
if (Attribute.IsDefined(property, typeof(HiddenAttribute)))
|
||||
continue;
|
||||
if (property.Name.EndsWith("_oculto"))
|
||||
continue;
|
||||
|
||||
var grid = new Grid();
|
||||
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
|
||||
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
|
||||
|
||||
var label = new Label
|
||||
{
|
||||
Content = property.Name.Replace("_", " ") + ":",
|
||||
Margin = new Thickness(0, 0, 5, 0),
|
||||
VerticalAlignment = VerticalAlignment.Center
|
||||
};
|
||||
|
||||
Grid.SetColumn(label, 0);
|
||||
grid.Children.Add(label);
|
||||
|
||||
if (property.PropertyType == typeof(double) || property.PropertyType == typeof(float) || property.PropertyType == typeof(string) || property.PropertyType == typeof(int))
|
||||
{
|
||||
var textBox = new TextBox
|
||||
{
|
||||
Margin = new Thickness(0),
|
||||
MinWidth = 200,
|
||||
VerticalContentAlignment = VerticalAlignment.Center
|
||||
};
|
||||
|
||||
var binding = new Binding(property.Name)
|
||||
{
|
||||
Source = selectedObject,
|
||||
Mode = BindingMode.TwoWay,
|
||||
UpdateSourceTrigger = UpdateSourceTrigger.LostFocus
|
||||
};
|
||||
|
||||
if (property.PropertyType == typeof(float))
|
||||
{
|
||||
if (Application.Current.Resources.Contains("floatFormatter"))
|
||||
{
|
||||
binding.Converter = Application.Current.Resources["floatFormatter"] as IValueConverter;
|
||||
}
|
||||
}
|
||||
if (property.PropertyType == typeof(double))
|
||||
{
|
||||
if (Application.Current.Resources.Contains("doubleFormatter"))
|
||||
{
|
||||
binding.Converter = Application.Current.Resources["doubleFormatter"] as IValueConverter;
|
||||
}
|
||||
}
|
||||
|
||||
textBox.SetBinding(TextBox.TextProperty, binding);
|
||||
|
||||
textBox.KeyDown += (sender, e) =>
|
||||
{
|
||||
if (e.Key == Key.Enter || e.Key == Key.Down)
|
||||
{
|
||||
var request = new TraversalRequest(FocusNavigationDirection.Next);
|
||||
request.Wrapped = true;
|
||||
textBox.MoveFocus(request);
|
||||
}
|
||||
else if (e.Key == Key.Up)
|
||||
{
|
||||
var request = new TraversalRequest(FocusNavigationDirection.Previous);
|
||||
request.Wrapped = true;
|
||||
textBox.MoveFocus(request);
|
||||
}
|
||||
};
|
||||
|
||||
Grid.SetColumn(textBox, 1);
|
||||
grid.Children.Add(textBox);
|
||||
}
|
||||
else if (property.PropertyType == typeof(bool))
|
||||
{
|
||||
var checkBox = new CheckBox
|
||||
{
|
||||
Margin = new Thickness(5, 0, 0, 0),
|
||||
VerticalAlignment = VerticalAlignment.Center
|
||||
};
|
||||
|
||||
var binding = new Binding(property.Name)
|
||||
{
|
||||
Source = selectedObject,
|
||||
Mode = BindingMode.TwoWay
|
||||
};
|
||||
|
||||
checkBox.SetBinding(CheckBox.IsCheckedProperty, binding);
|
||||
|
||||
checkBox.KeyDown += (sender, e) =>
|
||||
{
|
||||
if (e.Key == Key.Enter || e.Key == Key.Down)
|
||||
{
|
||||
var request = new TraversalRequest(FocusNavigationDirection.Next);
|
||||
request.Wrapped = true;
|
||||
checkBox.MoveFocus(request);
|
||||
}
|
||||
else if (e.Key == Key.Up)
|
||||
{
|
||||
var request = new TraversalRequest(FocusNavigationDirection.Previous);
|
||||
request.Wrapped = true;
|
||||
checkBox.MoveFocus(request);
|
||||
}
|
||||
};
|
||||
|
||||
Grid.SetColumn(checkBox, 1);
|
||||
grid.Children.Add(checkBox);
|
||||
}
|
||||
else if (property.PropertyType == typeof(Brush))
|
||||
{
|
||||
var comboBox = new ComboBox
|
||||
{
|
||||
ItemsSource = new List<Tuple<string, SolidColorBrush>>
|
||||
{
|
||||
Tuple.Create("Rojo", Brushes.Red),
|
||||
Tuple.Create("Azul", Brushes.Blue),
|
||||
Tuple.Create("Negro", Brushes.Black),
|
||||
Tuple.Create("Verde", Brushes.Green),
|
||||
Tuple.Create("Gris", Brushes.Gray)
|
||||
},
|
||||
SelectedValuePath = "Item2",
|
||||
Margin = new Thickness(0),
|
||||
MinWidth = 200
|
||||
};
|
||||
|
||||
var binding = new Binding(property.Name)
|
||||
{
|
||||
Source = selectedObject,
|
||||
Mode = BindingMode.TwoWay,
|
||||
UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
|
||||
};
|
||||
|
||||
comboBox.SetBinding(ComboBox.SelectedValueProperty, binding);
|
||||
|
||||
comboBox.KeyDown += (sender, e) =>
|
||||
{
|
||||
if (e.Key == Key.Enter || e.Key == Key.Down)
|
||||
{
|
||||
var request = new TraversalRequest(FocusNavigationDirection.Next);
|
||||
request.Wrapped = true;
|
||||
comboBox.MoveFocus(request);
|
||||
}
|
||||
else if (e.Key == Key.Up)
|
||||
{
|
||||
var request = new TraversalRequest(FocusNavigationDirection.Previous);
|
||||
request.Wrapped = true;
|
||||
comboBox.MoveFocus(request);
|
||||
}
|
||||
};
|
||||
|
||||
var template = new DataTemplate();
|
||||
var stackPanelFactory = new FrameworkElementFactory(typeof(StackPanel));
|
||||
stackPanelFactory.SetValue(StackPanel.OrientationProperty, Orientation.Horizontal);
|
||||
|
||||
var rectangleFactory = new FrameworkElementFactory(typeof(Rectangle));
|
||||
rectangleFactory.SetValue(Rectangle.WidthProperty, 16.0);
|
||||
rectangleFactory.SetValue(Rectangle.HeightProperty, 16.0);
|
||||
rectangleFactory.SetBinding(Rectangle.FillProperty, new Binding("Item2"));
|
||||
stackPanelFactory.AppendChild(rectangleFactory);
|
||||
|
||||
var textBlockFactory = new FrameworkElementFactory(typeof(TextBlock));
|
||||
textBlockFactory.SetBinding(TextBlock.TextProperty, new Binding("Item1"));
|
||||
stackPanelFactory.AppendChild(textBlockFactory);
|
||||
|
||||
template.VisualTree = stackPanelFactory;
|
||||
comboBox.ItemTemplate = template;
|
||||
|
||||
Grid.SetColumn(comboBox, 1);
|
||||
grid.Children.Add(comboBox);
|
||||
}
|
||||
PanelEdicion.Children.Add(grid);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public static List<string> CargarPropiedadesosDatosTags(Object selectedObject, StackPanel PanelEdicion, ResourceDictionary Resources)
|
||||
{
|
||||
PanelEdicion.Children.Clear();
|
||||
var properties = selectedObject.GetType().GetProperties();
|
||||
List<string> tags = new List<string>();
|
||||
|
||||
foreach (var property in properties)
|
||||
{
|
||||
if (Attribute.IsDefined(property, typeof(HiddenAttribute)))
|
||||
continue;
|
||||
if (property.Name.EndsWith("_oculto"))
|
||||
continue;
|
||||
|
||||
var grid = new Grid();
|
||||
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
|
||||
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
|
||||
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
|
||||
|
||||
var label = new Label
|
||||
{
|
||||
Content = property.Name.Replace("_", " ") + ":",
|
||||
Margin = new Thickness(0, 0, 5, 0),
|
||||
VerticalAlignment = VerticalAlignment.Center
|
||||
};
|
||||
|
||||
Grid.SetColumn(label, 0);
|
||||
grid.Children.Add(label);
|
||||
|
||||
if (property.PropertyType == typeof(double) || property.PropertyType == typeof(float) || property.PropertyType == typeof(string) || property.PropertyType == typeof(int))
|
||||
{
|
||||
var textBox = new TextBox
|
||||
{
|
||||
Margin = new Thickness(0),
|
||||
MinWidth = 200,
|
||||
VerticalContentAlignment = VerticalAlignment.Center
|
||||
};
|
||||
|
||||
var binding = new Binding(property.Name)
|
||||
{
|
||||
Source = selectedObject,
|
||||
Mode = BindingMode.TwoWay,
|
||||
UpdateSourceTrigger = UpdateSourceTrigger.LostFocus
|
||||
};
|
||||
|
||||
if (property.PropertyType == typeof(float))
|
||||
{
|
||||
if (Resources != null)
|
||||
binding.Converter = (FloatToFormattedStringConverter)Resources["floatFormatter"];
|
||||
}
|
||||
if (property.PropertyType == typeof(double))
|
||||
{
|
||||
if (Resources != null)
|
||||
binding.Converter = (DoubleToFormattedStringConverter)Resources["doubleFormatter"];
|
||||
}
|
||||
|
||||
textBox.SetBinding(TextBox.TextProperty, binding);
|
||||
|
||||
Grid.SetColumn(textBox, 1);
|
||||
grid.Children.Add(textBox);
|
||||
|
||||
var tagTextBox = new TextBox
|
||||
{
|
||||
Margin = new Thickness(0),
|
||||
MinWidth = 100,
|
||||
VerticalContentAlignment = VerticalAlignment.Center
|
||||
};
|
||||
|
||||
// Add an empty string to the tags list and get the index
|
||||
tags.Add(string.Empty);
|
||||
int tagIndex = tags.Count - 1;
|
||||
|
||||
// Event handler to update the tags list when the text changes
|
||||
tagTextBox.TextChanged += (sender, args) =>
|
||||
{
|
||||
tags[tagIndex] = tagTextBox.Text;
|
||||
};
|
||||
|
||||
Grid.SetColumn(tagTextBox, 2);
|
||||
grid.Children.Add(tagTextBox);
|
||||
}
|
||||
else if (property.PropertyType == typeof(bool))
|
||||
{
|
||||
var checkBox = new CheckBox
|
||||
{
|
||||
Margin = new Thickness(5, 0, 0, 0),
|
||||
VerticalAlignment = VerticalAlignment.Center
|
||||
};
|
||||
|
||||
var binding = new Binding(property.Name)
|
||||
{
|
||||
Source = selectedObject,
|
||||
Mode = BindingMode.TwoWay
|
||||
};
|
||||
|
||||
checkBox.SetBinding(CheckBox.IsCheckedProperty, binding);
|
||||
|
||||
Grid.SetColumn(checkBox, 1);
|
||||
grid.Children.Add(checkBox);
|
||||
}
|
||||
else if (property.PropertyType == typeof(Brush))
|
||||
{
|
||||
var listBox = new ListBox
|
||||
{
|
||||
ItemsSource = new List<string> { "Rojo", "Azul", "Negro", "Verde", "Gris" },
|
||||
Margin = new Thickness(0),
|
||||
MinWidth = 200
|
||||
};
|
||||
|
||||
listBox.SelectionChanged += (sender, e) =>
|
||||
{
|
||||
if (listBox.SelectedItem != null)
|
||||
{
|
||||
switch (listBox.SelectedItem.ToString())
|
||||
{
|
||||
case "Rojo":
|
||||
property.SetValue(selectedObject, Brushes.Red);
|
||||
break;
|
||||
case "Azul":
|
||||
property.SetValue(selectedObject, Brushes.Blue);
|
||||
break;
|
||||
case "Negro":
|
||||
property.SetValue(selectedObject, Brushes.Black);
|
||||
break;
|
||||
case "Verde":
|
||||
property.SetValue(selectedObject, Brushes.Green);
|
||||
break;
|
||||
case "Gris":
|
||||
property.SetValue(selectedObject, Brushes.Gray);
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var binding = new Binding(property.Name)
|
||||
{
|
||||
Source = selectedObject,
|
||||
Mode = BindingMode.TwoWay,
|
||||
Converter = new BrushToColorNameConverter()
|
||||
};
|
||||
|
||||
listBox.SetBinding(ListBox.SelectedItemProperty, binding);
|
||||
|
||||
Grid.SetColumn(listBox, 1);
|
||||
grid.Children.Add(listBox);
|
||||
}
|
||||
|
||||
PanelEdicion.Children.Add(grid);
|
||||
}
|
||||
|
||||
return tags;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -62,7 +62,7 @@ namespace CtrEditor.ObjetosSim
|
|||
[JsonIgnore]
|
||||
private Storyboard _storyboard;
|
||||
private System.Threading.Timer timer = null;
|
||||
|
||||
|
||||
[ObservableProperty]
|
||||
private float left;
|
||||
|
||||
|
@ -83,14 +83,6 @@ namespace CtrEditor.ObjetosSim
|
|||
[ObservableProperty]
|
||||
private float top;
|
||||
|
||||
[ObservableProperty]
|
||||
private string group_Panel;
|
||||
|
||||
[ObservableProperty]
|
||||
private bool enable_on_all_pages;
|
||||
|
||||
|
||||
|
||||
partial void OnTopChanged(float value)
|
||||
{
|
||||
CanvasSetTopinMeter(value);
|
||||
|
@ -104,6 +96,66 @@ namespace CtrEditor.ObjetosSim
|
|||
public virtual void TopChanged(float value) { }
|
||||
public virtual void TopChanging(float oldValue, float newValue) { }
|
||||
|
||||
|
||||
// Group
|
||||
[ObservableProperty]
|
||||
private string group_Panel;
|
||||
|
||||
// All Pages Objects
|
||||
[NotifyPropertyChangedFor(nameof(Show_on_this_page))]
|
||||
[ObservableProperty]
|
||||
private bool enable_on_all_pages;
|
||||
|
||||
partial void OnEnable_on_all_pagesChanged(bool value)
|
||||
{
|
||||
if (!value)
|
||||
Show_on_this_page = true;
|
||||
}
|
||||
|
||||
private List<string> Show_on_this_pages_oculto;
|
||||
|
||||
private bool show_on_this_page;
|
||||
public bool Show_on_this_page
|
||||
{
|
||||
get
|
||||
{
|
||||
// Not global object
|
||||
if (!enable_on_all_pages)
|
||||
{
|
||||
if (Show_on_this_pages_oculto != null)
|
||||
Show_on_this_pages_oculto.Clear();
|
||||
Show_on_this_pages_oculto = null;
|
||||
show_on_this_page = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Global Object
|
||||
if (Show_on_this_pages_oculto == null)
|
||||
Show_on_this_pages_oculto = new List<string>();
|
||||
if (_mainViewModel == null || _mainViewModel.SelectedImage == null) show_on_this_page = false;
|
||||
else show_on_this_page = Show_on_this_pages_oculto.Contains(_mainViewModel.SelectedImage);
|
||||
}
|
||||
return show_on_this_page;
|
||||
}
|
||||
set
|
||||
{
|
||||
// global object?
|
||||
if (enable_on_all_pages)
|
||||
{
|
||||
// Global Object
|
||||
if (Show_on_this_pages_oculto == null)
|
||||
Show_on_this_pages_oculto = new List<string>();
|
||||
if (_mainViewModel == null || _mainViewModel.SelectedImage == null) return;
|
||||
|
||||
if (value && !Show_on_this_pages_oculto.Contains(_mainViewModel.SelectedImage))
|
||||
Show_on_this_pages_oculto.Add(_mainViewModel.SelectedImage);
|
||||
else if (!value && Show_on_this_pages_oculto.Contains(_mainViewModel.SelectedImage))
|
||||
Show_on_this_pages_oculto.Remove(_mainViewModel.SelectedImage);
|
||||
}
|
||||
SetProperty(ref show_on_this_page, value);
|
||||
}
|
||||
}
|
||||
|
||||
private async void TimerCallback(object state)
|
||||
{
|
||||
await Task.Delay(500); // Esperar 0.5 segundos antes de ejecutar la función
|
||||
|
@ -111,7 +163,7 @@ namespace CtrEditor.ObjetosSim
|
|||
{
|
||||
// Realiza tus cambios en la interfaz de usuario aquí
|
||||
OnTimerAfterMovement();
|
||||
});
|
||||
});
|
||||
}
|
||||
/// <summary>
|
||||
/// Este timer se usa para llamar a OnTimerAfterMovement luego de que han pasado 500ms sin que se
|
||||
|
@ -122,7 +174,7 @@ namespace CtrEditor.ObjetosSim
|
|||
/// </summary>
|
||||
public void ResetTimer()
|
||||
{
|
||||
if (timer == null)
|
||||
if (timer == null)
|
||||
timer = new System.Threading.Timer(TimerCallback, null, Timeout.Infinite, Timeout.Infinite);
|
||||
|
||||
timer.Change(500, Timeout.Infinite);
|
||||
|
@ -446,7 +498,7 @@ namespace CtrEditor.ObjetosSim
|
|||
|
||||
public Vector2 PixelsToMeters(Vector2 pixel)
|
||||
{
|
||||
return new Vector2(PixelsToMeters(pixel.X),PixelsToMeters(pixel.Y));
|
||||
return new Vector2(PixelsToMeters(pixel.X), PixelsToMeters(pixel.Y));
|
||||
}
|
||||
|
||||
public float MeterToPixels(float meter)
|
||||
|
@ -476,7 +528,7 @@ namespace CtrEditor.ObjetosSim
|
|||
return transformGroup;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public (Vector2 TopLeft, Vector2 BottomRight) GetRectangleCoordinatesInMeter(Rectangle rect)
|
||||
{
|
||||
if (rect != null)
|
||||
|
|
|
@ -7,10 +7,55 @@ using System.Reflection;
|
|||
using Xceed.Wpf.Toolkit.PropertyGrid.Editors;
|
||||
using Xceed.Wpf.Toolkit;
|
||||
using Xceed.Wpf.Toolkit.PropertyGrid;
|
||||
using CtrEditor.ObjetosSim.Extraccion_Datos;
|
||||
using CtrEditor.ObjetosSim;
|
||||
using System.Collections.ObjectModel;
|
||||
|
||||
namespace CtrEditor
|
||||
{
|
||||
|
||||
public class SubclassFilterConverter : IValueConverter
|
||||
{
|
||||
public Type TargetType { get; set; }
|
||||
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
if (value is ObservableCollection<osBase> collection && TargetType != null)
|
||||
{
|
||||
var filteredCollection = new ObservableCollection<osBase>(collection.Where(x => x.GetType() == TargetType));
|
||||
return filteredCollection;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class BoolToVisibilityConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
if (value is bool boolValue)
|
||||
{
|
||||
return boolValue ? Visibility.Visible : Visibility.Collapsed;
|
||||
}
|
||||
return Visibility.Collapsed;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
if (value is Visibility visibility)
|
||||
{
|
||||
return visibility == Visibility.Visible;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public class DecimalEditor : ITypeEditor
|
||||
{
|
||||
public FrameworkElement ResolveEditor(PropertyItem propertyItem)
|
||||
|
|
Loading…
Reference in New Issue