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();
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
@@ -137,5 +137,21 @@ public interface ISelectionProcessor {
|
||||
*
|
||||
* @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);
|
||||
}
|
||||
|
||||
@@ -1946,6 +1946,42 @@ public class Presenter implements IPlugInPort {
|
||||
messageDispatcher.dispatchMessage(EventType.REPAINT);
|
||||
}
|
||||
}
|
||||
|
||||
@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
|
||||
public void refresh() {
|
||||
|
||||
@@ -55,6 +55,7 @@ Box
|
||||
C-B-E BJT
|
||||
Circle
|
||||
Coil(s)
|
||||
Component reordering is possible only when Project Explorer is sorted by z-index
|
||||
Configuration
|
||||
Could not apply changes. Check the log for details.
|
||||
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.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashSet;
|
||||
@@ -30,18 +31,26 @@ import org.apache.log4j.Logger;
|
||||
import org.diylc.common.IPlugInPort;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
import org.diylc.lang.LangUtil;
|
||||
import org.diylc.swing.ISwingUI;
|
||||
import org.diylc.swing.gui.ComponentPopupMenu;
|
||||
import org.diylc.swing.gui.DragDropList;
|
||||
import org.diylc.swing.gui.IDragDropListListener;
|
||||
import org.diylc.swing.gui.SearchTextField;
|
||||
|
||||
public class ExplorerPane extends JPanel {
|
||||
|
||||
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);
|
||||
|
||||
public static Font DEFAULT_FONT = new Font("Square721 BT", Font.PLAIN, 12);
|
||||
|
||||
private ISwingUI swingUI;
|
||||
private IPlugInPort plugInPort;
|
||||
|
||||
private JTextField searchField;
|
||||
private JScrollPane componentScrollPane;
|
||||
private ComponentListModel componentListModel;
|
||||
@@ -49,8 +58,9 @@ public class ExplorerPane extends JPanel {
|
||||
private ComponentPopupMenu popupMenu;
|
||||
private JComboBox<Sort> sortBox;
|
||||
|
||||
public ExplorerPane(IPlugInPort plugInPort) {
|
||||
public ExplorerPane(ISwingUI swingUI, IPlugInPort plugInPort) {
|
||||
super();
|
||||
this.swingUI = swingUI;
|
||||
this.plugInPort = plugInPort;
|
||||
setName("Project Explorer");
|
||||
|
||||
@@ -64,14 +74,6 @@ public class ExplorerPane extends JPanel {
|
||||
gbc.gridwidth = 1;
|
||||
|
||||
add(getSearchField(), gbc);
|
||||
|
||||
gbc.gridy++;
|
||||
|
||||
gbc.fill = GridBagConstraints.HORIZONTAL;
|
||||
gbc.weightx = 0;
|
||||
gbc.weighty = 0;
|
||||
|
||||
add(getSortBox(), gbc);
|
||||
|
||||
gbc.gridy++;
|
||||
|
||||
@@ -81,6 +83,14 @@ public class ExplorerPane extends JPanel {
|
||||
|
||||
add(getComponentScrollPane(), gbc);
|
||||
|
||||
gbc.gridy++;
|
||||
|
||||
gbc.fill = GridBagConstraints.HORIZONTAL;
|
||||
gbc.weightx = 0;
|
||||
gbc.weighty = 0;
|
||||
|
||||
add(getSortBox(), gbc);
|
||||
|
||||
setPreferredSize(new Dimension(180, 200));
|
||||
}
|
||||
|
||||
@@ -117,7 +127,18 @@ public class ExplorerPane extends JPanel {
|
||||
|
||||
public JList<IDIYComponent<?>> getComponentList() {
|
||||
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.setFont(DEFAULT_FONT);
|
||||
componentList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
|
||||
@@ -183,8 +204,10 @@ public class ExplorerPane extends JPanel {
|
||||
return popupMenu;
|
||||
}
|
||||
|
||||
public void setComponents(List<IDIYComponent<?>> components) {
|
||||
public void setComponents(List<IDIYComponent<?>> components,
|
||||
Collection<IDIYComponent<?>> selectedComponents) {
|
||||
this.getComponentListModel().setComponents(components);
|
||||
setSelection(new HashSet<IDIYComponent<?>>(selectedComponents));
|
||||
}
|
||||
|
||||
public void setSelection(Set<IDIYComponent<?>> selectedComponents) {
|
||||
@@ -230,7 +253,7 @@ public class ExplorerPane extends JPanel {
|
||||
private List<IDIYComponent<?>> components;
|
||||
|
||||
private String searchText;
|
||||
private Sort sort;
|
||||
private Sort sort = Sort.Z_INDEX;
|
||||
|
||||
public void setComponents(List<IDIYComponent<?>> components) {
|
||||
this.componentsRaw = components;
|
||||
@@ -243,6 +266,10 @@ public class ExplorerPane extends JPanel {
|
||||
return components;
|
||||
}
|
||||
|
||||
public Sort getSort() {
|
||||
return sort;
|
||||
}
|
||||
|
||||
public void setSort(Sort sort) {
|
||||
this.sort = sort;
|
||||
|
||||
|
||||
@@ -64,10 +64,10 @@ public class ExplorerPlugin implements IPlugIn {
|
||||
public void processMessage(EventType eventType, Object... params) {
|
||||
switch (eventType) {
|
||||
case PROJECT_MODIFIED:
|
||||
getExplorerPane().setComponents(((Project)params[1]).getComponents());
|
||||
getExplorerPane().setComponents(((Project)params[1]).getComponents(), plugInPort.getSelectedComponents());
|
||||
break;
|
||||
case PROJECT_LOADED:
|
||||
getExplorerPane().setComponents(((Project)params[0]).getComponents());
|
||||
getExplorerPane().setComponents(((Project)params[0]).getComponents(), plugInPort.getSelectedComponents());
|
||||
break;
|
||||
case SELECTION_CHANGED:
|
||||
getExplorerPane().setSelection((Set<IDIYComponent<?>>)params[0]);
|
||||
@@ -103,7 +103,7 @@ public class ExplorerPlugin implements IPlugIn {
|
||||
|
||||
public ExplorerPane getExplorerPane() {
|
||||
if (explorerPane == null) {
|
||||
explorerPane = new ExplorerPane(plugInPort);
|
||||
explorerPane = new ExplorerPane(swingUI, plugInPort);
|
||||
}
|
||||
return explorerPane;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user