Mejorado de delete y dumplicate para objetos multiples

This commit is contained in:
Miguel 2025-03-31 13:40:28 +02:00
parent 736068619a
commit fe8f2119ce
4 changed files with 109 additions and 9 deletions

View File

@ -18,6 +18,12 @@ namespace CtrEditor.Controls
UserControlFactory.CargarPropiedadesosDatos(selectedObject, PropertyGridControl);
}
// Add a new method to clear properties
public void ClearProperties()
{
UserControlFactory.LimpiarPropiedadesosDatos(PropertyGridControl);
}
public bool IsKeyboardFocusWithin => PropertyGridControl.IsKeyboardFocusWithin;
private void ImagePathButton_Click(object sender, RoutedEventArgs e)

View File

@ -273,10 +273,9 @@ namespace CtrEditor
partial void OnSelectedItemOsListChanged(osBase value)
{
if (value != null)
habilitarEliminarUserControl = true;
else
habilitarEliminarUserControl = false;
// Enable delete and duplicate commands when either an individual item is selected
// or when there are multiple objects selected
habilitarEliminarUserControl = _objectManager.SelectedObjects.Count > 0;
}
@ -519,8 +518,66 @@ namespace CtrEditor
private void DuplicarUserControl()
{
if (SelectedItemOsList is osBase objDuplicar)
DuplicarObjeto(objDuplicar, 0.5f, 0.5f);
if (_objectManager.SelectedObjects.Count > 0)
{
// Create a copy of the selected objects to avoid issues during iteration
var objectsToDuplicate = _objectManager.SelectedObjects.ToList();
// Clear current selection before duplicating
_objectManager.ClearSelection();
// Track all newly created objects
var newObjects = new List<osBase>();
// Duplicate each object with a small offset
float offsetX = 0.5f;
float offsetY = 0.5f;
foreach (var objToDuplicate in objectsToDuplicate)
{
var newObj = DuplicarObjeto(objToDuplicate, offsetX, offsetY);
if (newObj != null)
{
newObjects.Add(newObj);
}
}
// Force a complete layout update to ensure all controls are positioned
MainWindow.ImagenEnTrabajoCanvas.UpdateLayout();
// Use a dispatcher to delay the selection until the UI has had time to fully render
Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Render, new Action(() =>
{
// Select all newly created objects
foreach (var newObj in newObjects)
{
if (newObj.VisualRepresentation != null)
{
double left = Canvas.GetLeft(newObj.VisualRepresentation);
double top = Canvas.GetTop(newObj.VisualRepresentation);
// Only add to selection if the object has valid coordinates
if (!double.IsNaN(left) && !double.IsNaN(top) && !double.IsInfinity(left) && !double.IsInfinity(top))
{
_objectManager.SelectObject(newObj);
}
}
}
// Force another layout update before updating selection visuals
MainWindow.ImagenEnTrabajoCanvas.UpdateLayout();
// Update SelectedItemOsList if there are newly created objects
if (newObjects.Count > 0)
{
// Set to the last duplicated object so it's visible in the property panel
SelectedItemOsList = newObjects.LastOrDefault();
}
// Now update selection visuals
_objectManager.UpdateSelectionVisuals();
}));
}
}
public osBase DuplicarObjeto(osBase objDuplicar, float OffsetX, float OffsetY)
@ -575,6 +632,7 @@ namespace CtrEditor
private void EliminarUserControl()
{
_objectManager.EliminarObjetosSeleccionados();
SelectedItemOsList = null;
}
@ -887,7 +945,15 @@ namespace CtrEditor
// Se cargan los datos de cada UserControl en el StackPanel
public void CargarPropiedadesosDatos(osBase selectedObject, Controls.PanelEdicionControl PanelEdicion, ResourceDictionary Resources)
{
PanelEdicion.CargarPropiedades(selectedObject);
if (selectedObject == null)
{
// Clear the property panel when no object is selected
PanelEdicion.ClearProperties();
}
else
{
PanelEdicion.CargarPropiedades(selectedObject);
}
}
private RelayCommand saveCommand;
@ -1010,6 +1076,12 @@ namespace CtrEditor
HasUnsavedChanges = true;
_objectManager.UpdateSelectionVisuals();
}
// Add this method to MainViewModel class
public void NotifySelectionChanged()
{
OnPropertyChanged(nameof(SelectedItemOsList));
}
}
public class SimulationData

View File

@ -319,7 +319,6 @@ namespace CtrEditor
private void ListaOs_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
{
if (e.AddedItems.Count > 0 && e.AddedItems[0] is osBase selectedObject)
{
// Siempre trabajar con selección única para las propiedades
@ -327,8 +326,10 @@ namespace CtrEditor
_objectManager.SelectObject(selectedObject);
}
else
else if (e.RemovedItems.Count > 0 && e.AddedItems.Count == 0)
{
// This handles the case when an item is deselected and no new item is selected
CargarPropiedadesosDatos(null);
_objectManager.RemoveResizeRectangles();
}
}
@ -367,6 +368,7 @@ namespace CtrEditor
{
if (e.Key == Key.Delete)
{
// This will delete all selected objects
_objectManager.EliminarObjetosSeleccionados();
e.Handled = true;
}
@ -443,7 +445,15 @@ namespace CtrEditor
private void CargarPropiedadesosDatos(osBase selectedObject)
{
if (DataContext is MainViewModel viewModel)
{
viewModel.CargarPropiedadesosDatos(selectedObject, PanelEdicion, Resources);
// If no object is selected, make sure to clear the properties panel
if (selectedObject == null)
{
PanelEdicion.ClearProperties();
}
}
}
public (float X, float Y) ObtenerCentroCanvasMeters()

View File

@ -429,6 +429,9 @@ namespace CtrEditor
}
UpdateSelectionVisuals();
// Update the view model's selection state
vm.NotifySelectionChanged();
}
}
}
@ -440,6 +443,12 @@ namespace CtrEditor
_selectedObjects.Remove(obj);
obj.IsSelected = false;
RemoveSelectionHighlight(obj.VisualRepresentation);
// Update the view model's selection state
if (_mainWindow.DataContext is MainViewModel vm)
{
vm.NotifySelectionChanged();
}
}
}
@ -899,6 +908,9 @@ namespace CtrEditor
RemoveResizeRectangles();
RemoveAllSelectionHighlights();
// Ensure the property panel is cleared by explicitly setting SelectedItemOsList to null
viewModel.SelectedItemOsList = null;
// Actualizar el estado de cambios sin guardar
if (viewModel != null)
{