mirror of
https://github.com/bancika/diy-layout-creator
synced 2026-11-11 01:32:08 +10:00
Allow drag and drop reordering in project explorer
This commit is contained in:
@@ -342,16 +342,6 @@ public interface IPlugInPort extends ISelectionProcessor, IMouseProcessor, IKeyP
|
|||||||
// */
|
// */
|
||||||
// Rectangle2D getSelectedAreaRect();
|
// Rectangle2D getSelectedAreaRect();
|
||||||
|
|
||||||
/**
|
|
||||||
* Sends each of the selected components one step back.
|
|
||||||
*/
|
|
||||||
void sendSelectionToBack();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Brings each of the selected components one step to front.
|
|
||||||
*/
|
|
||||||
void bringSelectionToFront();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Causes the display to refresh.
|
* Causes the display to refresh.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -138,4 +138,20 @@ public interface ISelectionProcessor {
|
|||||||
* @param model
|
* @param model
|
||||||
*/
|
*/
|
||||||
void applyModelToSelection(String[] model);
|
void applyModelToSelection(String[] model);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends each of the selected components one step back.
|
||||||
|
*/
|
||||||
|
void sendSelectionToBack();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Brings each of the selected components one step to front.
|
||||||
|
*/
|
||||||
|
void bringSelectionToFront();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Move selected components to z index starting from the provided value
|
||||||
|
* @param zIndex
|
||||||
|
*/
|
||||||
|
void moveSelectionToZIndex(int zIndex);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1947,6 +1947,42 @@ public class Presenter implements IPlugInPort {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void moveSelectionToZIndex(int zIndex) {
|
||||||
|
LOG.info(String.format("moveSelectionToZIndex(%d)", zIndex));
|
||||||
|
Project oldProject = currentProject.clone();
|
||||||
|
|
||||||
|
// sort the selection in Z-order
|
||||||
|
List<IDIYComponent<?>> selection = new ArrayList<IDIYComponent<?>>(selectedComponents);
|
||||||
|
Collections.sort(selection, new Comparator<IDIYComponent<?>>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compare(IDIYComponent<?> o1, IDIYComponent<?> o2) {
|
||||||
|
return new Integer(currentProject.getComponents().indexOf(o1))
|
||||||
|
.compareTo(currentProject.getComponents().indexOf(o2));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
for (IDIYComponent<?> component : selection) {
|
||||||
|
int index = currentProject.getComponents().indexOf(component);
|
||||||
|
if (index < 0) {
|
||||||
|
LOG.warn("Component not found in the project: " + component.getName());
|
||||||
|
} else {
|
||||||
|
if (index < zIndex)
|
||||||
|
zIndex--;
|
||||||
|
|
||||||
|
currentProject.getComponents().remove(index);
|
||||||
|
currentProject.getComponents().add(zIndex, component);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!oldProject.equals(currentProject)) {
|
||||||
|
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject,
|
||||||
|
"Change Z-order");
|
||||||
|
projectFileManager.notifyFileChange();
|
||||||
|
messageDispatcher.dispatchMessage(EventType.REPAINT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void refresh() {
|
public void refresh() {
|
||||||
LOG.info("refresh()");
|
LOG.info("refresh()");
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ Box
|
|||||||
C-B-E BJT
|
C-B-E BJT
|
||||||
Circle
|
Circle
|
||||||
Coil(s)
|
Coil(s)
|
||||||
|
Component reordering is possible only when Project Explorer is sorted by z-index
|
||||||
Configuration
|
Configuration
|
||||||
Could not apply changes. Check the log for details.
|
Could not apply changes. Check the log for details.
|
||||||
D-G-S JFET
|
D-G-S JFET
|
||||||
|
|||||||
@@ -0,0 +1,129 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* DIY Layout Creator (DIYLC). Copyright (c) 2009-2018 held jointly by the individual authors.
|
||||||
|
*
|
||||||
|
* This file is part of DIYLC.
|
||||||
|
*
|
||||||
|
* DIYLC is free software: you can redistribute it and/or modify it under the terms of the GNU
|
||||||
|
* General Public License as published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* DIYLC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
||||||
|
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||||
|
* Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with DIYLC. If not, see
|
||||||
|
* <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.diylc.swing.gui;
|
||||||
|
|
||||||
|
import java.awt.datatransfer.DataFlavor;
|
||||||
|
import java.awt.datatransfer.StringSelection;
|
||||||
|
import java.awt.datatransfer.Transferable;
|
||||||
|
import java.awt.dnd.DnDConstants;
|
||||||
|
import java.awt.dnd.DragGestureEvent;
|
||||||
|
import java.awt.dnd.DragGestureListener;
|
||||||
|
import java.awt.dnd.DragSource;
|
||||||
|
import java.awt.dnd.DragSourceDragEvent;
|
||||||
|
import java.awt.dnd.DragSourceDropEvent;
|
||||||
|
import java.awt.dnd.DragSourceEvent;
|
||||||
|
import java.awt.dnd.DragSourceListener;
|
||||||
|
import javax.swing.DropMode;
|
||||||
|
import javax.swing.JList;
|
||||||
|
import javax.swing.TransferHandler;
|
||||||
|
|
||||||
|
public class DragDropList<T> extends JList<T> {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public DragDropList(IDragDropListListener listener) {
|
||||||
|
super();
|
||||||
|
setDragEnabled(true);
|
||||||
|
setDropMode(DropMode.INSERT);
|
||||||
|
|
||||||
|
setTransferHandler(new MyListDropHandler(this, listener));
|
||||||
|
|
||||||
|
new MyDragListener(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MyDragListener implements DragSourceListener, DragGestureListener {
|
||||||
|
|
||||||
|
DragDropList<?> list;
|
||||||
|
DragSource ds = new DragSource();
|
||||||
|
|
||||||
|
public MyDragListener(DragDropList<?> list) {
|
||||||
|
this.list = list;
|
||||||
|
ds.createDefaultDragGestureRecognizer(list, DnDConstants.ACTION_MOVE, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void dragGestureRecognized(DragGestureEvent dge) {
|
||||||
|
StringSelection transferable = new StringSelection(Integer.toString(list.getSelectedIndex()));
|
||||||
|
ds.startDrag(dge, DragSource.DefaultMoveDrop, transferable, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void dragEnter(DragSourceDragEvent dsde) {}
|
||||||
|
|
||||||
|
public void dragExit(DragSourceEvent dse) {}
|
||||||
|
|
||||||
|
public void dragOver(DragSourceDragEvent dsde) {}
|
||||||
|
|
||||||
|
public void dragDropEnd(DragSourceDropEvent dsde) {
|
||||||
|
// if (dsde.getDropSuccess()) {
|
||||||
|
// System.out.println("Succeeded");
|
||||||
|
// } else {
|
||||||
|
// System.out.println("Failed");
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
public void dropActionChanged(DragSourceDragEvent dsde) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MyListDropHandler extends TransferHandler {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
private DragDropList<?> dragDropList;
|
||||||
|
private IDragDropListListener listener;
|
||||||
|
|
||||||
|
public MyListDropHandler() {}
|
||||||
|
|
||||||
|
public MyListDropHandler(DragDropList<?> dragDropList, IDragDropListListener listener) {
|
||||||
|
this.dragDropList = dragDropList;
|
||||||
|
this.listener = listener;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean canImport(TransferHandler.TransferSupport support) {
|
||||||
|
if (!support.isDataFlavorSupported(DataFlavor.stringFlavor)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (support.getComponent() != dragDropList) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
JList.DropLocation dl = (JList.DropLocation) support.getDropLocation();
|
||||||
|
if (dl.getIndex() == -1) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean importData(TransferHandler.TransferSupport support) {
|
||||||
|
if (!canImport(support)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Transferable transferable = support.getTransferable();
|
||||||
|
String indexString;
|
||||||
|
try {
|
||||||
|
indexString = (String) transferable.getTransferData(DataFlavor.stringFlavor);
|
||||||
|
} catch (Exception e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int selectedIndex = Integer.parseInt(indexString);
|
||||||
|
JList.DropLocation dl = (JList.DropLocation) support.getDropLocation();
|
||||||
|
int dropTargetIndex = dl.getIndex();
|
||||||
|
|
||||||
|
return listener.dropComplete(selectedIndex, dropTargetIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* DIY Layout Creator (DIYLC). Copyright (c) 2009-2018 held jointly by the individual authors.
|
||||||
|
*
|
||||||
|
* This file is part of DIYLC.
|
||||||
|
*
|
||||||
|
* DIYLC is free software: you can redistribute it and/or modify it under the terms of the GNU
|
||||||
|
* General Public License as published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* DIYLC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
||||||
|
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||||
|
* Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with DIYLC. If not, see
|
||||||
|
* <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.diylc.swing.gui;
|
||||||
|
|
||||||
|
public interface IDragDropListListener {
|
||||||
|
boolean dropComplete(int selectedIndex, int dropTargetIndex);
|
||||||
|
}
|
||||||
@@ -10,6 +10,7 @@ import java.awt.event.MouseAdapter;
|
|||||||
import java.awt.event.MouseEvent;
|
import java.awt.event.MouseEvent;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
@@ -30,18 +31,26 @@ import org.apache.log4j.Logger;
|
|||||||
import org.diylc.common.IPlugInPort;
|
import org.diylc.common.IPlugInPort;
|
||||||
import org.diylc.core.IDIYComponent;
|
import org.diylc.core.IDIYComponent;
|
||||||
import org.diylc.lang.LangUtil;
|
import org.diylc.lang.LangUtil;
|
||||||
|
import org.diylc.swing.ISwingUI;
|
||||||
import org.diylc.swing.gui.ComponentPopupMenu;
|
import org.diylc.swing.gui.ComponentPopupMenu;
|
||||||
|
import org.diylc.swing.gui.DragDropList;
|
||||||
|
import org.diylc.swing.gui.IDragDropListListener;
|
||||||
import org.diylc.swing.gui.SearchTextField;
|
import org.diylc.swing.gui.SearchTextField;
|
||||||
|
|
||||||
public class ExplorerPane extends JPanel {
|
public class ExplorerPane extends JPanel {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private static final String REORDERING_NOT_POSSIBLE = LangUtil.translate(
|
||||||
|
"Component reordering is possible only when Project Explorer is sorted by z-index.");
|
||||||
|
|
||||||
private static final Logger LOG = Logger.getLogger(ExplorerPane.class);
|
private static final Logger LOG = Logger.getLogger(ExplorerPane.class);
|
||||||
|
|
||||||
public static Font DEFAULT_FONT = new Font("Square721 BT", Font.PLAIN, 12);
|
public static Font DEFAULT_FONT = new Font("Square721 BT", Font.PLAIN, 12);
|
||||||
|
|
||||||
|
private ISwingUI swingUI;
|
||||||
private IPlugInPort plugInPort;
|
private IPlugInPort plugInPort;
|
||||||
|
|
||||||
private JTextField searchField;
|
private JTextField searchField;
|
||||||
private JScrollPane componentScrollPane;
|
private JScrollPane componentScrollPane;
|
||||||
private ComponentListModel componentListModel;
|
private ComponentListModel componentListModel;
|
||||||
@@ -49,8 +58,9 @@ public class ExplorerPane extends JPanel {
|
|||||||
private ComponentPopupMenu popupMenu;
|
private ComponentPopupMenu popupMenu;
|
||||||
private JComboBox<Sort> sortBox;
|
private JComboBox<Sort> sortBox;
|
||||||
|
|
||||||
public ExplorerPane(IPlugInPort plugInPort) {
|
public ExplorerPane(ISwingUI swingUI, IPlugInPort plugInPort) {
|
||||||
super();
|
super();
|
||||||
|
this.swingUI = swingUI;
|
||||||
this.plugInPort = plugInPort;
|
this.plugInPort = plugInPort;
|
||||||
setName("Project Explorer");
|
setName("Project Explorer");
|
||||||
|
|
||||||
@@ -67,20 +77,20 @@ public class ExplorerPane extends JPanel {
|
|||||||
|
|
||||||
gbc.gridy++;
|
gbc.gridy++;
|
||||||
|
|
||||||
gbc.fill = GridBagConstraints.HORIZONTAL;
|
|
||||||
gbc.weightx = 0;
|
|
||||||
gbc.weighty = 0;
|
|
||||||
|
|
||||||
add(getSortBox(), gbc);
|
|
||||||
|
|
||||||
gbc.gridy++;
|
|
||||||
|
|
||||||
gbc.fill = GridBagConstraints.BOTH;
|
gbc.fill = GridBagConstraints.BOTH;
|
||||||
gbc.weighty = 1;
|
gbc.weighty = 1;
|
||||||
gbc.weightx = 1;
|
gbc.weightx = 1;
|
||||||
|
|
||||||
add(getComponentScrollPane(), gbc);
|
add(getComponentScrollPane(), gbc);
|
||||||
|
|
||||||
|
gbc.gridy++;
|
||||||
|
|
||||||
|
gbc.fill = GridBagConstraints.HORIZONTAL;
|
||||||
|
gbc.weightx = 0;
|
||||||
|
gbc.weighty = 0;
|
||||||
|
|
||||||
|
add(getSortBox(), gbc);
|
||||||
|
|
||||||
setPreferredSize(new Dimension(180, 200));
|
setPreferredSize(new Dimension(180, 200));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,7 +127,18 @@ public class ExplorerPane extends JPanel {
|
|||||||
|
|
||||||
public JList<IDIYComponent<?>> getComponentList() {
|
public JList<IDIYComponent<?>> getComponentList() {
|
||||||
if (componentList == null) {
|
if (componentList == null) {
|
||||||
componentList = new JList<IDIYComponent<?>>();
|
componentList = new DragDropList<IDIYComponent<?>>(new IDragDropListListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean dropComplete(int selectedIndex, int dropTargetIndex) {
|
||||||
|
if (getComponentListModel().getSort() != Sort.Z_INDEX) {
|
||||||
|
swingUI.showMessage(REORDERING_NOT_POSSIBLE, "Error", ISwingUI.ERROR_MESSAGE);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
plugInPort.moveSelectionToZIndex(getComponentListModel().getSize() - dropTargetIndex);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
componentList.setModel(getComponentListModel());
|
componentList.setModel(getComponentListModel());
|
||||||
componentList.setFont(DEFAULT_FONT);
|
componentList.setFont(DEFAULT_FONT);
|
||||||
componentList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
|
componentList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
|
||||||
@@ -183,8 +204,10 @@ public class ExplorerPane extends JPanel {
|
|||||||
return popupMenu;
|
return popupMenu;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setComponents(List<IDIYComponent<?>> components) {
|
public void setComponents(List<IDIYComponent<?>> components,
|
||||||
|
Collection<IDIYComponent<?>> selectedComponents) {
|
||||||
this.getComponentListModel().setComponents(components);
|
this.getComponentListModel().setComponents(components);
|
||||||
|
setSelection(new HashSet<IDIYComponent<?>>(selectedComponents));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSelection(Set<IDIYComponent<?>> selectedComponents) {
|
public void setSelection(Set<IDIYComponent<?>> selectedComponents) {
|
||||||
@@ -230,7 +253,7 @@ public class ExplorerPane extends JPanel {
|
|||||||
private List<IDIYComponent<?>> components;
|
private List<IDIYComponent<?>> components;
|
||||||
|
|
||||||
private String searchText;
|
private String searchText;
|
||||||
private Sort sort;
|
private Sort sort = Sort.Z_INDEX;
|
||||||
|
|
||||||
public void setComponents(List<IDIYComponent<?>> components) {
|
public void setComponents(List<IDIYComponent<?>> components) {
|
||||||
this.componentsRaw = components;
|
this.componentsRaw = components;
|
||||||
@@ -243,6 +266,10 @@ public class ExplorerPane extends JPanel {
|
|||||||
return components;
|
return components;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Sort getSort() {
|
||||||
|
return sort;
|
||||||
|
}
|
||||||
|
|
||||||
public void setSort(Sort sort) {
|
public void setSort(Sort sort) {
|
||||||
this.sort = sort;
|
this.sort = sort;
|
||||||
|
|
||||||
|
|||||||
@@ -64,10 +64,10 @@ public class ExplorerPlugin implements IPlugIn {
|
|||||||
public void processMessage(EventType eventType, Object... params) {
|
public void processMessage(EventType eventType, Object... params) {
|
||||||
switch (eventType) {
|
switch (eventType) {
|
||||||
case PROJECT_MODIFIED:
|
case PROJECT_MODIFIED:
|
||||||
getExplorerPane().setComponents(((Project)params[1]).getComponents());
|
getExplorerPane().setComponents(((Project)params[1]).getComponents(), plugInPort.getSelectedComponents());
|
||||||
break;
|
break;
|
||||||
case PROJECT_LOADED:
|
case PROJECT_LOADED:
|
||||||
getExplorerPane().setComponents(((Project)params[0]).getComponents());
|
getExplorerPane().setComponents(((Project)params[0]).getComponents(), plugInPort.getSelectedComponents());
|
||||||
break;
|
break;
|
||||||
case SELECTION_CHANGED:
|
case SELECTION_CHANGED:
|
||||||
getExplorerPane().setSelection((Set<IDIYComponent<?>>)params[0]);
|
getExplorerPane().setSelection((Set<IDIYComponent<?>>)params[0]);
|
||||||
@@ -103,7 +103,7 @@ public class ExplorerPlugin implements IPlugIn {
|
|||||||
|
|
||||||
public ExplorerPane getExplorerPane() {
|
public ExplorerPane getExplorerPane() {
|
||||||
if (explorerPane == null) {
|
if (explorerPane == null) {
|
||||||
explorerPane = new ExplorerPane(plugInPort);
|
explorerPane = new ExplorerPane(swingUI, plugInPort);
|
||||||
}
|
}
|
||||||
return explorerPane;
|
return explorerPane;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user