mirror of
https://github.com/bancika/diy-layout-creator
synced 2026-11-10 17:22:09 +10:00
Added Project Explorer
This commit is contained in:
@@ -51,8 +51,9 @@ public interface ISelectionProcessor {
|
|||||||
* with all components that are stuck to the newly selected components.
|
* with all components that are stuck to the newly selected components.
|
||||||
*
|
*
|
||||||
* @param newSelection
|
* @param newSelection
|
||||||
|
* @param panToSelection
|
||||||
*/
|
*/
|
||||||
void updateSelection(Collection<IDIYComponent<?>> newSelection);
|
void setSelection(Collection<IDIYComponent<?>> newSelection, boolean panToSelection);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds all components at the specified location, sorted by z-index from top to bottom. Location
|
* Finds all components at the specified location, sorted by z-index from top to bottom. Location
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ public abstract class AbstractComponent<T> implements IDIYComponent<T> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return name;
|
return name == null ? "(null)" : name;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -674,7 +674,7 @@ public class Presenter implements IPlugInPort {
|
|||||||
}
|
}
|
||||||
// Notify the listeners.
|
// Notify the listeners.
|
||||||
if (!oldProject.equals(currentProject)) {
|
if (!oldProject.equals(currentProject)) {
|
||||||
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject.clone(), "Add "
|
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject, "Add "
|
||||||
+ componentTypeSlot.getName());
|
+ componentTypeSlot.getName());
|
||||||
drawingManager.clearContinuityArea();
|
drawingManager.clearContinuityArea();
|
||||||
projectFileManager.notifyFileChange();
|
projectFileManager.notifyFileChange();
|
||||||
@@ -798,7 +798,7 @@ public class Presenter implements IPlugInPort {
|
|||||||
mirrorComponents(this.selectedComponents, IComponentTransformer.VERTICAL, snapToGrid);
|
mirrorComponents(this.selectedComponents, IComponentTransformer.VERTICAL, snapToGrid);
|
||||||
} else
|
} else
|
||||||
return false;
|
return false;
|
||||||
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject.clone(),
|
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject,
|
||||||
"Rotate Selection");
|
"Rotate Selection");
|
||||||
messageDispatcher.dispatchMessage(EventType.REPAINT);
|
messageDispatcher.dispatchMessage(EventType.REPAINT);
|
||||||
drawingManager.clearContinuityArea();
|
drawingManager.clearContinuityArea();
|
||||||
@@ -842,7 +842,7 @@ public class Presenter implements IPlugInPort {
|
|||||||
|
|
||||||
Project oldProject = currentProject.clone();
|
Project oldProject = currentProject.clone();
|
||||||
moveComponents(controlPointMap, dx, dy, snapToGrid, snapToObjects);
|
moveComponents(controlPointMap, dx, dy, snapToGrid, snapToObjects);
|
||||||
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject.clone(), "Move Selection");
|
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject, "Move Selection");
|
||||||
messageDispatcher.dispatchMessage(EventType.REPAINT);
|
messageDispatcher.dispatchMessage(EventType.REPAINT);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -1060,7 +1060,7 @@ public class Presenter implements IPlugInPort {
|
|||||||
|
|
||||||
Project oldProject = currentProject.clone();
|
Project oldProject = currentProject.clone();
|
||||||
moveComponents(controlPointMap, dx, dy, false, false);
|
moveComponents(controlPointMap, dx, dy, false, false);
|
||||||
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject.clone(), "Move Selection");
|
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject, "Move Selection");
|
||||||
messageDispatcher.dispatchMessage(EventType.REPAINT);
|
messageDispatcher.dispatchMessage(EventType.REPAINT);
|
||||||
drawingManager.clearContinuityArea();
|
drawingManager.clearContinuityArea();
|
||||||
}
|
}
|
||||||
@@ -1427,7 +1427,7 @@ public class Presenter implements IPlugInPort {
|
|||||||
LOG.trace("Rotating selected components");
|
LOG.trace("Rotating selected components");
|
||||||
Project oldProject = currentProject.clone();
|
Project oldProject = currentProject.clone();
|
||||||
rotateComponents(this.selectedComponents, direction, isSnapToGrid());
|
rotateComponents(this.selectedComponents, direction, isSnapToGrid());
|
||||||
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject.clone(),
|
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject,
|
||||||
"Rotate Selection");
|
"Rotate Selection");
|
||||||
drawingManager.clearContinuityArea();
|
drawingManager.clearContinuityArea();
|
||||||
messageDispatcher.dispatchMessage(EventType.REPAINT);
|
messageDispatcher.dispatchMessage(EventType.REPAINT);
|
||||||
@@ -1540,7 +1540,7 @@ public class Presenter implements IPlugInPort {
|
|||||||
|
|
||||||
mirrorComponents(selectedComponents, direction, isSnapToGrid());
|
mirrorComponents(selectedComponents, direction, isSnapToGrid());
|
||||||
|
|
||||||
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject.clone(),
|
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject,
|
||||||
MIRROR_SELECTION);
|
MIRROR_SELECTION);
|
||||||
messageDispatcher.dispatchMessage(EventType.REPAINT);
|
messageDispatcher.dispatchMessage(EventType.REPAINT);
|
||||||
drawingManager.clearContinuityArea();
|
drawingManager.clearContinuityArea();
|
||||||
@@ -1675,7 +1675,7 @@ public class Presenter implements IPlugInPort {
|
|||||||
// operation.
|
// operation.
|
||||||
|
|
||||||
if (!preDragProject.equals(currentProject)) {
|
if (!preDragProject.equals(currentProject)) {
|
||||||
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, preDragProject, currentProject.clone(), "Drag");
|
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, preDragProject, currentProject, "Drag");
|
||||||
drawingManager.clearContinuityArea();
|
drawingManager.clearContinuityArea();
|
||||||
projectFileManager.notifyFileChange();
|
projectFileManager.notifyFileChange();
|
||||||
}
|
}
|
||||||
@@ -1725,7 +1725,7 @@ public class Presenter implements IPlugInPort {
|
|||||||
|
|
||||||
updateSelection(newSelection);
|
updateSelection(newSelection);
|
||||||
|
|
||||||
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject.clone(), "Duplicate");
|
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject, "Duplicate");
|
||||||
drawingManager.clearContinuityArea();
|
drawingManager.clearContinuityArea();
|
||||||
projectFileManager.notifyFileChange();
|
projectFileManager.notifyFileChange();
|
||||||
messageDispatcher.dispatchMessage(EventType.REPAINT);
|
messageDispatcher.dispatchMessage(EventType.REPAINT);
|
||||||
@@ -1749,7 +1749,7 @@ public class Presenter implements IPlugInPort {
|
|||||||
currentProject.getComponents().removeAll(selectedComponents);
|
currentProject.getComponents().removeAll(selectedComponents);
|
||||||
DrawingCache.Instance.invalidate(selectedComponents);
|
DrawingCache.Instance.invalidate(selectedComponents);
|
||||||
|
|
||||||
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject.clone(), "Delete");
|
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject, "Delete");
|
||||||
drawingManager.clearContinuityArea();
|
drawingManager.clearContinuityArea();
|
||||||
projectFileManager.notifyFileChange();
|
projectFileManager.notifyFileChange();
|
||||||
updateSelection(EMPTY_SELECTION);
|
updateSelection(EMPTY_SELECTION);
|
||||||
@@ -1784,7 +1784,7 @@ public class Presenter implements IPlugInPort {
|
|||||||
// Notify the listeners.
|
// Notify the listeners.
|
||||||
messageDispatcher.dispatchMessage(EventType.REPAINT);
|
messageDispatcher.dispatchMessage(EventType.REPAINT);
|
||||||
if (!oldProject.equals(currentProject)) {
|
if (!oldProject.equals(currentProject)) {
|
||||||
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject.clone(), "Group");
|
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject, "Group");
|
||||||
projectFileManager.notifyFileChange();
|
projectFileManager.notifyFileChange();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1797,7 +1797,7 @@ public class Presenter implements IPlugInPort {
|
|||||||
// Notify the listeners.
|
// Notify the listeners.
|
||||||
messageDispatcher.dispatchMessage(EventType.REPAINT);
|
messageDispatcher.dispatchMessage(EventType.REPAINT);
|
||||||
if (!oldProject.equals(currentProject)) {
|
if (!oldProject.equals(currentProject)) {
|
||||||
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject.clone(), "Ungroup");
|
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject, "Ungroup");
|
||||||
projectFileManager.notifyFileChange();
|
projectFileManager.notifyFileChange();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1815,7 +1815,7 @@ public class Presenter implements IPlugInPort {
|
|||||||
messageDispatcher.dispatchMessage(EventType.REPAINT);
|
messageDispatcher.dispatchMessage(EventType.REPAINT);
|
||||||
messageDispatcher.dispatchMessage(EventType.LAYER_STATE_CHANGED, currentProject.getLockedLayers());
|
messageDispatcher.dispatchMessage(EventType.LAYER_STATE_CHANGED, currentProject.getLockedLayers());
|
||||||
if (!oldProject.equals(currentProject)) {
|
if (!oldProject.equals(currentProject)) {
|
||||||
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject.clone(),
|
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject,
|
||||||
locked ? "Lock Layer" : "Unlock Layer");
|
locked ? "Lock Layer" : "Unlock Layer");
|
||||||
projectFileManager.notifyFileChange();
|
projectFileManager.notifyFileChange();
|
||||||
}
|
}
|
||||||
@@ -1834,7 +1834,7 @@ public class Presenter implements IPlugInPort {
|
|||||||
messageDispatcher.dispatchMessage(EventType.REPAINT);
|
messageDispatcher.dispatchMessage(EventType.REPAINT);
|
||||||
messageDispatcher.dispatchMessage(EventType.LAYER_VISIBILITY_CHANGED, currentProject.getHiddenLayers());
|
messageDispatcher.dispatchMessage(EventType.LAYER_VISIBILITY_CHANGED, currentProject.getHiddenLayers());
|
||||||
if (!oldProject.equals(currentProject)) {
|
if (!oldProject.equals(currentProject)) {
|
||||||
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject.clone(),
|
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject,
|
||||||
visible ? "Show Layer" : "Hide Layer");
|
visible ? "Show Layer" : "Hide Layer");
|
||||||
projectFileManager.notifyFileChange();
|
projectFileManager.notifyFileChange();
|
||||||
}
|
}
|
||||||
@@ -1887,7 +1887,7 @@ public class Presenter implements IPlugInPort {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!oldProject.equals(currentProject)) {
|
if (!oldProject.equals(currentProject)) {
|
||||||
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject.clone(), "Send to Back");
|
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject, "Send to Back");
|
||||||
projectFileManager.notifyFileChange();
|
projectFileManager.notifyFileChange();
|
||||||
messageDispatcher.dispatchMessage(EventType.REPAINT);
|
messageDispatcher.dispatchMessage(EventType.REPAINT);
|
||||||
}
|
}
|
||||||
@@ -1940,7 +1940,7 @@ public class Presenter implements IPlugInPort {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!oldProject.equals(currentProject)) {
|
if (!oldProject.equals(currentProject)) {
|
||||||
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject.clone(),
|
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject,
|
||||||
"Bring to Front");
|
"Bring to Front");
|
||||||
projectFileManager.notifyFileChange();
|
projectFileManager.notifyFileChange();
|
||||||
messageDispatcher.dispatchMessage(EventType.REPAINT);
|
messageDispatcher.dispatchMessage(EventType.REPAINT);
|
||||||
@@ -2033,13 +2033,18 @@ public class Presenter implements IPlugInPort {
|
|||||||
.getComponents()));
|
.getComponents()));
|
||||||
}
|
}
|
||||||
|
|
||||||
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject.clone(),
|
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject,
|
||||||
"Renumber selection");
|
"Renumber selection");
|
||||||
projectFileManager.notifyFileChange();
|
projectFileManager.notifyFileChange();
|
||||||
messageDispatcher.dispatchMessage(EventType.REPAINT);
|
messageDispatcher.dispatchMessage(EventType.REPAINT);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateSelection(Collection<IDIYComponent<?>> newSelection) {
|
public void setSelection(Collection<IDIYComponent<?>> newSelection, boolean panToSelection) {
|
||||||
|
this.updateSelection(newSelection);
|
||||||
|
messageDispatcher.dispatchMessage(EventType.REPAINT, panToSelection);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateSelection(Collection<IDIYComponent<?>> newSelection) {
|
||||||
this.selectedComponents = new HashSet<IDIYComponent<?>>(newSelection);
|
this.selectedComponents = new HashSet<IDIYComponent<?>>(newSelection);
|
||||||
Map<IDIYComponent<?>, Set<Integer>> controlPointMap = new HashMap<IDIYComponent<?>, Set<Integer>>();
|
Map<IDIYComponent<?>, Set<Integer>> controlPointMap = new HashMap<IDIYComponent<?>, Set<Integer>>();
|
||||||
for (IDIYComponent<?> component : selectedComponents) {
|
for (IDIYComponent<?> component : selectedComponents) {
|
||||||
@@ -2342,7 +2347,7 @@ public class Presenter implements IPlugInPort {
|
|||||||
} finally {
|
} finally {
|
||||||
// Notify the listeners.
|
// Notify the listeners.
|
||||||
if (!oldProject.equals(currentProject)) {
|
if (!oldProject.equals(currentProject)) {
|
||||||
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject.clone(),
|
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject,
|
||||||
"Edit Selection");
|
"Edit Selection");
|
||||||
drawingManager.clearContinuityArea();
|
drawingManager.clearContinuityArea();
|
||||||
projectFileManager.notifyFileChange();
|
projectFileManager.notifyFileChange();
|
||||||
@@ -2380,7 +2385,7 @@ public class Presenter implements IPlugInPort {
|
|||||||
} finally {
|
} finally {
|
||||||
// Notify the listeners.
|
// Notify the listeners.
|
||||||
if (!oldProject.equals(currentProject)) {
|
if (!oldProject.equals(currentProject)) {
|
||||||
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject.clone(),
|
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject,
|
||||||
"Edit Project");
|
"Edit Project");
|
||||||
drawingManager.clearContinuityArea();
|
drawingManager.clearContinuityArea();
|
||||||
projectFileManager.notifyFileChange();
|
projectFileManager.notifyFileChange();
|
||||||
@@ -2403,7 +2408,7 @@ public class Presenter implements IPlugInPort {
|
|||||||
} finally {
|
} finally {
|
||||||
// Notify the listeners.
|
// Notify the listeners.
|
||||||
if (!oldProject.equals(currentProject)) {
|
if (!oldProject.equals(currentProject)) {
|
||||||
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject.clone(),
|
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject,
|
||||||
editor.getEditAction());
|
editor.getEditAction());
|
||||||
drawingManager.clearContinuityArea();
|
drawingManager.clearContinuityArea();
|
||||||
projectFileManager.notifyFileChange();
|
projectFileManager.notifyFileChange();
|
||||||
@@ -2426,7 +2431,7 @@ public class Presenter implements IPlugInPort {
|
|||||||
// Notify the listeners.
|
// Notify the listeners.
|
||||||
if (!oldProject.equals(currentProject)) {
|
if (!oldProject.equals(currentProject)) {
|
||||||
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject,
|
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject,
|
||||||
currentProject.clone(), "Edit Project");
|
currentProject, "Edit Project");
|
||||||
drawingManager.clearContinuityArea();
|
drawingManager.clearContinuityArea();
|
||||||
projectFileManager.notifyFileChange();
|
projectFileManager.notifyFileChange();
|
||||||
}
|
}
|
||||||
@@ -2652,7 +2657,7 @@ public class Presenter implements IPlugInPort {
|
|||||||
|
|
||||||
// Notify the listeners.
|
// Notify the listeners.
|
||||||
if (!oldProject.equals(currentProject)) {
|
if (!oldProject.equals(currentProject)) {
|
||||||
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject.clone(),
|
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject,
|
||||||
"Edit Selection");
|
"Edit Selection");
|
||||||
drawingManager.clearContinuityArea();
|
drawingManager.clearContinuityArea();
|
||||||
projectFileManager.notifyFileChange();
|
projectFileManager.notifyFileChange();
|
||||||
@@ -2718,7 +2723,7 @@ public class Presenter implements IPlugInPort {
|
|||||||
} finally {
|
} finally {
|
||||||
// Notify the listeners.
|
// Notify the listeners.
|
||||||
if (!oldProject.equals(currentProject)) {
|
if (!oldProject.equals(currentProject)) {
|
||||||
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject.clone(),
|
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject,
|
||||||
locked ? "Lock Component" : "Unlock Component");
|
locked ? "Lock Component" : "Unlock Component");
|
||||||
projectFileManager.notifyFileChange();
|
projectFileManager.notifyFileChange();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4188,7 +4188,11 @@
|
|||||||
<changes>
|
<changes>
|
||||||
<org.diylc.appframework.update.Change>
|
<org.diylc.appframework.update.Change>
|
||||||
<changeType>NEW_FEATURE</changeType>
|
<changeType>NEW_FEATURE</changeType>
|
||||||
<description>Keyboard shortcuts for toggling layer visibility using Ctrl + 1 through Ctrl + 5</description>
|
<description>Added Project Explorer pane in the right-hand side for quick access to components</description>
|
||||||
|
</org.diylc.appframework.update.Change>
|
||||||
|
<org.diylc.appframework.update.Change>
|
||||||
|
<changeType>NEW_FEATURE</changeType>
|
||||||
|
<description>Keyboard shortcuts for toggling layer visibility using Ctrl + 1 through Ctrl + 6</description>
|
||||||
</org.diylc.appframework.update.Change>
|
</org.diylc.appframework.update.Change>
|
||||||
<org.diylc.appframework.update.Change>
|
<org.diylc.appframework.update.Change>
|
||||||
<changeType>IMPROVEMENT</changeType>
|
<changeType>IMPROVEMENT</changeType>
|
||||||
|
|||||||
Binary file not shown.
@@ -133,9 +133,13 @@ SPDT (On/Off/On)
|
|||||||
SPDT (On/On)
|
SPDT (On/On)
|
||||||
SPST
|
SPST
|
||||||
Shorting
|
Shorting
|
||||||
|
Show Project Explorer
|
||||||
Single - North
|
Single - North
|
||||||
Single - South
|
Single - South
|
||||||
Six
|
Six
|
||||||
|
Sort by Name
|
||||||
|
Sort by Type
|
||||||
|
Sort by Z-index
|
||||||
Source Style
|
Source Style
|
||||||
Source Type
|
Source Type
|
||||||
Srpski
|
Srpski
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@@ -1821,7 +1821,7 @@ public class ActionFactory {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void valueChanged(String key, Object value) {
|
public void valueChanged(String key, Object value) {
|
||||||
putValue(AbstractAction.SELECTED_KEY, (Boolean) value);
|
putValue(AbstractAction.SELECTED_KEY, Boolean.TRUE.equals(value));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,9 +54,10 @@ public interface ISwingUI extends IView {
|
|||||||
* @param component
|
* @param component
|
||||||
* @param position
|
* @param position
|
||||||
* @param collapsible
|
* @param collapsible
|
||||||
|
* @param visibilityConfigKey in case of a collapsible view, this config key is used to persist the state
|
||||||
* @throws BadPositionException in case invalid position is specified
|
* @throws BadPositionException in case invalid position is specified
|
||||||
*/
|
*/
|
||||||
void injectGUIComponent(JComponent component, int position, boolean collapsible) throws BadPositionException;
|
void injectGUIComponent(JComponent component, int position, boolean collapsible, String visibilityConfigKey) throws BadPositionException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Injects a custom menu action into application's main menu. If <code>action</code> is set to
|
* Injects a custom menu action into application's main menu. If <code>action</code> is set to
|
||||||
|
|||||||
@@ -1,23 +1,20 @@
|
|||||||
/*
|
/*
|
||||||
|
*
|
||||||
DIY Layout Creator (DIYLC).
|
* DIY Layout Creator (DIYLC). Copyright (c) 2009-2018 held jointly by the individual authors.
|
||||||
Copyright (c) 2009-2018 held jointly by the individual authors.
|
*
|
||||||
|
* This file is part of DIYLC.
|
||||||
This file is part of DIYLC.
|
*
|
||||||
|
* DIYLC is free software: you can redistribute it and/or modify it under the terms of the GNU
|
||||||
DIYLC is free software: you can redistribute it and/or modify
|
* General Public License as published by the Free Software Foundation, either version 3 of the
|
||||||
it under the terms of the GNU General Public License as published by
|
* License, or (at your option) any later version.
|
||||||
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
|
||||||
DIYLC is distributed in the hope that it will be useful,
|
* Public License for more details.
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
*
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* You should have received a copy of the GNU General Public License along with DIYLC. If not, see
|
||||||
GNU General Public License for more details.
|
* <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
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;
|
package org.diylc.swing.gui;
|
||||||
|
|
||||||
@@ -30,9 +27,13 @@ import java.awt.event.ComponentListener;
|
|||||||
import java.awt.event.MouseAdapter;
|
import java.awt.event.MouseAdapter;
|
||||||
import java.awt.event.MouseEvent;
|
import java.awt.event.MouseEvent;
|
||||||
import java.awt.event.MouseListener;
|
import java.awt.event.MouseListener;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Optional;
|
||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
import javax.swing.SwingConstants;
|
import javax.swing.SwingConstants;
|
||||||
import javax.swing.border.MatteBorder;
|
import javax.swing.border.MatteBorder;
|
||||||
|
import org.diylc.appframework.miscutils.ConfigurationManager;
|
||||||
|
import org.diylc.appframework.miscutils.IConfigListener;
|
||||||
|
|
||||||
/***
|
/***
|
||||||
* Panel that has a clickable line that can used to collapse and expand the contents of the panel.
|
* Panel that has a clickable line that can used to collapse and expand the contents of the panel.
|
||||||
@@ -46,6 +47,7 @@ public class CollapsiblePanel extends JPanel {
|
|||||||
private static int BORDER_THICKNESS = 4;
|
private static int BORDER_THICKNESS = 4;
|
||||||
|
|
||||||
private MatteBorderEx border;
|
private MatteBorderEx border;
|
||||||
|
private String visibilityConfigKey;
|
||||||
|
|
||||||
private Color defaultColor = Color.lightGray;
|
private Color defaultColor = Color.lightGray;
|
||||||
private Color highlightColor = Color.decode("#66CCFF");
|
private Color highlightColor = Color.decode("#66CCFF");
|
||||||
@@ -54,7 +56,8 @@ public class CollapsiblePanel extends JPanel {
|
|||||||
*
|
*
|
||||||
* @param position designates the direction in which the panel should collapse
|
* @param position designates the direction in which the panel should collapse
|
||||||
*/
|
*/
|
||||||
public CollapsiblePanel(int position) {
|
public CollapsiblePanel(int position, String visibilityConfigKey) {
|
||||||
|
this.visibilityConfigKey = visibilityConfigKey;
|
||||||
border = new MatteBorderEx(position == SwingConstants.BOTTOM ? BORDER_THICKNESS : 0,
|
border = new MatteBorderEx(position == SwingConstants.BOTTOM ? BORDER_THICKNESS : 0,
|
||||||
position == SwingConstants.RIGHT ? BORDER_THICKNESS : 0,
|
position == SwingConstants.RIGHT ? BORDER_THICKNESS : 0,
|
||||||
position == SwingConstants.TOP ? BORDER_THICKNESS : 0,
|
position == SwingConstants.TOP ? BORDER_THICKNESS : 0,
|
||||||
@@ -64,6 +67,15 @@ public class CollapsiblePanel extends JPanel {
|
|||||||
BorderLayout borderLayout = new BorderLayout();
|
BorderLayout borderLayout = new BorderLayout();
|
||||||
setLayout(borderLayout);
|
setLayout(borderLayout);
|
||||||
addMouseListener(mouseListener);
|
addMouseListener(mouseListener);
|
||||||
|
|
||||||
|
ConfigurationManager.getInstance().addConfigListener(visibilityConfigKey,
|
||||||
|
new IConfigListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void valueChanged(String key, Object value) {
|
||||||
|
toggleVisibility(Boolean.TRUE.equals(value));
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseListener mouseListener = new MouseAdapter() {
|
MouseListener mouseListener = new MouseAdapter() {
|
||||||
@@ -102,6 +114,7 @@ public class CollapsiblePanel extends JPanel {
|
|||||||
public void componentShown(ComponentEvent e) {
|
public void componentShown(ComponentEvent e) {
|
||||||
updateBorderTitle();
|
updateBorderTitle();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void componentHidden(ComponentEvent e) {
|
public void componentHidden(ComponentEvent e) {
|
||||||
updateBorderTitle();
|
updateBorderTitle();
|
||||||
@@ -113,6 +126,9 @@ public class CollapsiblePanel extends JPanel {
|
|||||||
comp.addComponentListener(contentComponentListener);
|
comp.addComponentListener(contentComponentListener);
|
||||||
Component r = super.add(comp);
|
Component r = super.add(comp);
|
||||||
updateBorderTitle();
|
updateBorderTitle();
|
||||||
|
if (!ConfigurationManager.getInstance().readBoolean(visibilityConfigKey, true)) {
|
||||||
|
comp.setVisible(false);
|
||||||
|
}
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,6 +137,9 @@ public class CollapsiblePanel extends JPanel {
|
|||||||
comp.addComponentListener(contentComponentListener);
|
comp.addComponentListener(contentComponentListener);
|
||||||
Component r = super.add(name, comp);
|
Component r = super.add(name, comp);
|
||||||
updateBorderTitle();
|
updateBorderTitle();
|
||||||
|
if (!ConfigurationManager.getInstance().readBoolean(visibilityConfigKey, true)) {
|
||||||
|
comp.setVisible(false);
|
||||||
|
}
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,6 +156,9 @@ public class CollapsiblePanel extends JPanel {
|
|||||||
comp.addComponentListener(contentComponentListener);
|
comp.addComponentListener(contentComponentListener);
|
||||||
super.add(comp, constraints);
|
super.add(comp, constraints);
|
||||||
updateBorderTitle();
|
updateBorderTitle();
|
||||||
|
if (!ConfigurationManager.getInstance().readBoolean(visibilityConfigKey, true)) {
|
||||||
|
comp.setVisible(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -144,6 +166,9 @@ public class CollapsiblePanel extends JPanel {
|
|||||||
comp.addComponentListener(contentComponentListener);
|
comp.addComponentListener(contentComponentListener);
|
||||||
super.add(comp, constraints, index);
|
super.add(comp, constraints, index);
|
||||||
updateBorderTitle();
|
updateBorderTitle();
|
||||||
|
if (!ConfigurationManager.getInstance().readBoolean(visibilityConfigKey, true)) {
|
||||||
|
comp.setVisible(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -168,7 +193,9 @@ public class CollapsiblePanel extends JPanel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void toggleVisibility() {
|
protected void toggleVisibility() {
|
||||||
toggleVisibility(hasInvisibleComponent());
|
boolean invisible = hasInvisibleComponent();
|
||||||
|
ConfigurationManager.getInstance().writeValue(visibilityConfigKey, invisible);
|
||||||
|
toggleVisibility(invisible);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void toggleVisibility(boolean visible) {
|
protected void toggleVisibility(boolean visible) {
|
||||||
@@ -179,7 +206,12 @@ public class CollapsiblePanel extends JPanel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void updateBorderTitle() {
|
protected void updateBorderTitle() {
|
||||||
|
boolean invisible = hasInvisibleComponent();
|
||||||
|
Optional<String> componentName = Arrays.stream(getComponents())
|
||||||
|
.map(x -> x.getName())
|
||||||
|
.filter(x -> x != null)
|
||||||
|
.findFirst();
|
||||||
|
setToolTipText("Click to " + (invisible ? "expand" : "collapse") + (componentName.isPresent() ? " " + componentName.get() : ""));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected final boolean hasInvisibleComponent() {
|
protected final boolean hasInvisibleComponent() {
|
||||||
|
|||||||
@@ -0,0 +1,511 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
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.Component;
|
||||||
|
import java.awt.Toolkit;
|
||||||
|
import java.awt.datatransfer.Clipboard;
|
||||||
|
import java.awt.datatransfer.ClipboardOwner;
|
||||||
|
import java.awt.datatransfer.Transferable;
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
import javax.swing.AbstractAction;
|
||||||
|
import javax.swing.JComponent;
|
||||||
|
import javax.swing.JMenu;
|
||||||
|
import javax.swing.JMenuItem;
|
||||||
|
import javax.swing.JPopupMenu;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
import org.diylc.clipboard.ComponentTransferable;
|
||||||
|
import org.diylc.common.ComponentType;
|
||||||
|
import org.diylc.common.IComponentTransformer;
|
||||||
|
import org.diylc.common.IPlugInPort;
|
||||||
|
import org.diylc.core.ExpansionMode;
|
||||||
|
import org.diylc.core.IDIYComponent;
|
||||||
|
import org.diylc.core.Template;
|
||||||
|
import org.diylc.swing.ActionFactory;
|
||||||
|
import org.diylc.swing.images.IconLoader;
|
||||||
|
import org.diylc.swing.plugins.toolbox.ComponentButtonFactory;
|
||||||
|
|
||||||
|
public class ComponentPopupMenu extends JPopupMenu implements ClipboardOwner {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private static final Logger LOG = Logger.getLogger(ComponentPopupMenu.class);
|
||||||
|
|
||||||
|
private JMenu selectionMenu;
|
||||||
|
private JMenu expandMenu;
|
||||||
|
private JMenu transformMenu;
|
||||||
|
private JMenu applyTemplateMenu;
|
||||||
|
private JMenu applyModelMenu;
|
||||||
|
private JMenu lockMenu;
|
||||||
|
private JMenu unlockMenu;
|
||||||
|
|
||||||
|
private ActionFactory.CutAction cutAction;
|
||||||
|
private ActionFactory.CopyAction copyAction;
|
||||||
|
private ActionFactory.PasteAction pasteAction;
|
||||||
|
private ActionFactory.DuplicateAction duplicateAction;
|
||||||
|
private ActionFactory.EditSelectionAction editSelectionAction;
|
||||||
|
private ActionFactory.DeleteSelectionAction deleteSelectionAction;
|
||||||
|
private ActionFactory.SaveAsTemplateAction saveAsTemplateAction;
|
||||||
|
private ActionFactory.SaveAsBlockAction saveAsBlockAction;
|
||||||
|
private ActionFactory.GroupAction groupAction;
|
||||||
|
private ActionFactory.UngroupAction ungroupAction;
|
||||||
|
private ActionFactory.SendToBackAction sendToBackAction;
|
||||||
|
private ActionFactory.BringToFrontAction bringToFrontAction;
|
||||||
|
private ActionFactory.NudgeAction nudgeAction;
|
||||||
|
private ActionFactory.ExpandSelectionAction expandSelectionAllAction;
|
||||||
|
private ActionFactory.ExpandSelectionAction expandSelectionImmediateAction;
|
||||||
|
private ActionFactory.ExpandSelectionAction expandSelectionSameTypeAction;
|
||||||
|
private ActionFactory.RotateSelectionAction rotateClockwiseAction;
|
||||||
|
private ActionFactory.RotateSelectionAction rotateCounterclockwiseAction;
|
||||||
|
private ActionFactory.MirrorSelectionAction mirrorHorizontallyAction;
|
||||||
|
private ActionFactory.MirrorSelectionAction mirrorVerticallyAction;
|
||||||
|
private ActionFactory.FlexibleLeadsAction flexibleLeadsAction;
|
||||||
|
|
||||||
|
private IPlugInPort plugInPort;
|
||||||
|
private Clipboard clipboard;
|
||||||
|
private JComponent owner;
|
||||||
|
|
||||||
|
public ComponentPopupMenu(IPlugInPort plugInPort, JComponent owner, boolean showSelectionMenu) {
|
||||||
|
this.plugInPort = plugInPort;
|
||||||
|
this.owner = owner;
|
||||||
|
this.clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
|
||||||
|
|
||||||
|
if (showSelectionMenu) {
|
||||||
|
add(getSelectionMenu());
|
||||||
|
addSeparator();
|
||||||
|
}
|
||||||
|
|
||||||
|
add(getCutAction());
|
||||||
|
add(getCopyAction());
|
||||||
|
add(getPasteAction());
|
||||||
|
add(getDuplicateAction());
|
||||||
|
addSeparator();
|
||||||
|
add(getEditSelectionAction());
|
||||||
|
add(getDeleteSelectionAction());
|
||||||
|
add(getTransformMenu());
|
||||||
|
add(getSaveAsTemplateAction());
|
||||||
|
add(getApplyTemplateMenu());
|
||||||
|
add(getApplyModelMenu());
|
||||||
|
add(getSaveAsBlockAction());
|
||||||
|
add(getExpandMenu());
|
||||||
|
addSeparator();
|
||||||
|
add(getLockMenu());
|
||||||
|
add(getUnlockMenu());
|
||||||
|
addSeparator();
|
||||||
|
add(getFlexibleLeadsAction());
|
||||||
|
addSeparator();
|
||||||
|
add(ActionFactory.getInstance().createEditProjectAction(plugInPort));
|
||||||
|
}
|
||||||
|
|
||||||
|
public JMenu getSelectionMenu() {
|
||||||
|
if (selectionMenu == null) {
|
||||||
|
selectionMenu = new TranslatedMenu("Select");
|
||||||
|
selectionMenu.setIcon(IconLoader.ElementsSelection.getIcon());
|
||||||
|
}
|
||||||
|
return selectionMenu;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JMenu getExpandMenu() {
|
||||||
|
if (expandMenu == null) {
|
||||||
|
expandMenu = new TranslatedMenu("Expand Selection");
|
||||||
|
expandMenu.setIcon(IconLoader.BranchAdd.getIcon());
|
||||||
|
expandMenu.add(getExpandSelectionAllAction());
|
||||||
|
expandMenu.add(getExpandSelectionImmediateAction());
|
||||||
|
expandMenu.add(getExpandSelectionSameTypeAction());
|
||||||
|
}
|
||||||
|
return expandMenu;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JMenu getLockMenu() {
|
||||||
|
if (lockMenu == null) {
|
||||||
|
lockMenu = new TranslatedMenu("Lock");
|
||||||
|
lockMenu.setIcon(IconLoader.Lock.getIcon());
|
||||||
|
}
|
||||||
|
return lockMenu;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JMenu getUnlockMenu() {
|
||||||
|
if (unlockMenu == null) {
|
||||||
|
unlockMenu = new TranslatedMenu("Unlock");
|
||||||
|
unlockMenu.setIcon(IconLoader.Unlock.getIcon());
|
||||||
|
}
|
||||||
|
return unlockMenu;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JMenu getTransformMenu() {
|
||||||
|
if (transformMenu == null) {
|
||||||
|
transformMenu = new TranslatedMenu("Transform Selection");
|
||||||
|
transformMenu.setIcon(IconLoader.MagicWand.getIcon());
|
||||||
|
transformMenu.add(getRotateClockwiseAction());
|
||||||
|
transformMenu.add(getRotateCounterclockwiseAction());
|
||||||
|
transformMenu.addSeparator();
|
||||||
|
transformMenu.add(getMirrorHorizontallyAction());
|
||||||
|
transformMenu.add(getMirrorVerticallyAction());
|
||||||
|
transformMenu.addSeparator();
|
||||||
|
transformMenu.add(getNudgeAction());
|
||||||
|
transformMenu.addSeparator();
|
||||||
|
transformMenu.add(getSendToBackAction());
|
||||||
|
transformMenu.add(getBringToFrontAction());
|
||||||
|
transformMenu.addSeparator();
|
||||||
|
transformMenu.add(getGroupAction());
|
||||||
|
transformMenu.add(getUngroupAction());
|
||||||
|
}
|
||||||
|
return transformMenu;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JMenu getApplyTemplateMenu() {
|
||||||
|
if (applyTemplateMenu == null) {
|
||||||
|
applyTemplateMenu = new TranslatedMenu("Apply Variant");
|
||||||
|
applyTemplateMenu.setIcon(IconLoader.BriefcaseInto.getIcon());
|
||||||
|
}
|
||||||
|
return applyTemplateMenu;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JMenu getApplyModelMenu() {
|
||||||
|
if (applyModelMenu == null) {
|
||||||
|
applyModelMenu = new TranslatedMenu("Apply Model");
|
||||||
|
applyModelMenu.setIcon(IconLoader.Barcode.getIcon());
|
||||||
|
}
|
||||||
|
return applyModelMenu;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void prepareAndShowAt(Collection<IDIYComponent<?>> componentsForSelection, Collection<IDIYComponent<?>> componentsForLock, int x, int y) {
|
||||||
|
boolean enabled = !plugInPort.getSelectedComponents().isEmpty();
|
||||||
|
getCutAction().setEnabled(enabled);
|
||||||
|
getCopyAction().setEnabled(enabled);
|
||||||
|
getDuplicateAction().setEnabled(enabled);
|
||||||
|
try {
|
||||||
|
getPasteAction().setEnabled(
|
||||||
|
clipboard.isDataFlavorAvailable(ComponentTransferable.listFlavor));
|
||||||
|
} catch (Exception ex) {
|
||||||
|
getPasteAction().setEnabled(false);
|
||||||
|
}
|
||||||
|
getEditSelectionAction().setEnabled(enabled);
|
||||||
|
getDeleteSelectionAction().setEnabled(enabled);
|
||||||
|
getExpandSelectionAllAction().setEnabled(enabled);
|
||||||
|
getExpandSelectionImmediateAction().setEnabled(enabled);
|
||||||
|
getExpandSelectionSameTypeAction().setEnabled(enabled);
|
||||||
|
getGroupAction().setEnabled(enabled);
|
||||||
|
getUngroupAction().setEnabled(enabled);
|
||||||
|
getNudgeAction().setEnabled(enabled);
|
||||||
|
getSendToBackAction().setEnabled(enabled);
|
||||||
|
getBringToFrontAction().setEnabled(enabled);
|
||||||
|
getRotateClockwiseAction().setEnabled(enabled);
|
||||||
|
getRotateCounterclockwiseAction().setEnabled(enabled);
|
||||||
|
getMirrorHorizontallyAction().setEnabled(enabled);
|
||||||
|
getMirrorVerticallyAction().setEnabled(enabled);
|
||||||
|
getFlexibleLeadsAction().setEnabled(enabled);
|
||||||
|
|
||||||
|
getSaveAsTemplateAction()
|
||||||
|
.setEnabled(plugInPort.getSelectedComponents().size() == 1);
|
||||||
|
getSaveAsBlockAction().setEnabled(plugInPort.getSelectedComponents().size() > 1);
|
||||||
|
|
||||||
|
updateSelectionMenu(componentsForSelection);
|
||||||
|
updateApplyTemplateMenu();
|
||||||
|
updateApplyModelMenu();
|
||||||
|
updateLock(componentsForLock);
|
||||||
|
show(owner, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateSelectionMenu(Collection<IDIYComponent<?>> componentsAt) {
|
||||||
|
getSelectionMenu().removeAll();
|
||||||
|
for (IDIYComponent<?> component : componentsAt) {
|
||||||
|
JMenuItem item = new JMenuItem(component.getName());
|
||||||
|
final IDIYComponent<?> finalComponent = component;
|
||||||
|
item.addActionListener(new ActionListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
List<IDIYComponent<?>> newSelection = new ArrayList<IDIYComponent<?>>();
|
||||||
|
newSelection.add(finalComponent);
|
||||||
|
plugInPort.setSelection(newSelection, false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
getSelectionMenu().add(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateApplyTemplateMenu() {
|
||||||
|
JMenu applyMenu = getApplyTemplateMenu();
|
||||||
|
applyMenu.removeAll();
|
||||||
|
List<Template> templates = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
templates = plugInPort.getVariantsForSelection();
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOG.info("Could not load variants for selection");
|
||||||
|
applyMenu.setEnabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (templates == null) {
|
||||||
|
applyMenu.setEnabled(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
applyMenu.setEnabled(templates.size() > 0);
|
||||||
|
|
||||||
|
for (Template template : templates) {
|
||||||
|
JMenuItem item = new JMenuItem(template.getName());
|
||||||
|
final Template finalTemplate = template;
|
||||||
|
item.addActionListener(new ActionListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
plugInPort.applyVariantToSelection(finalTemplate);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
applyMenu.add(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateApplyModelMenu() {
|
||||||
|
JMenu applyMenu = getApplyModelMenu();
|
||||||
|
applyMenu.removeAll();
|
||||||
|
|
||||||
|
Collection<ComponentType> selectedComponentTypes = plugInPort.getSelectedComponentTypes();
|
||||||
|
if (selectedComponentTypes.size() != 1) {
|
||||||
|
applyMenu.setEnabled(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ComponentType componentType = selectedComponentTypes.stream().findFirst().get();
|
||||||
|
List<String[]> datasheet = componentType.getDatasheet();
|
||||||
|
if (datasheet == null || datasheet.isEmpty()) {
|
||||||
|
applyMenu.setEnabled(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
applyMenu.setEnabled(true);
|
||||||
|
List<Component> datasheetItems = ComponentButtonFactory.createDatasheetItems(plugInPort, componentType, new ArrayList<String>(), model -> {
|
||||||
|
LOG.info("Applying datasheet model " + String.join(", ", model));
|
||||||
|
plugInPort.applyModelToSelection(model);
|
||||||
|
});
|
||||||
|
for (Component item : datasheetItems) {
|
||||||
|
applyMenu.add(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateLock(Collection<IDIYComponent<?>> componentsAt) {
|
||||||
|
getLockMenu().removeAll();
|
||||||
|
getUnlockMenu().removeAll();
|
||||||
|
if (componentsAt.size() == 0) {
|
||||||
|
getLockMenu().setEnabled(false);
|
||||||
|
getUnlockMenu().setEnabled(false);
|
||||||
|
} else {
|
||||||
|
boolean hasLocked = false;
|
||||||
|
boolean hasUnlocked = false;
|
||||||
|
for (IDIYComponent<?> c : componentsAt) {
|
||||||
|
if (plugInPort.getCurrentProject().getLockedComponents().contains(c)) {
|
||||||
|
getUnlockMenu().add(new LockAction(c, false));
|
||||||
|
hasLocked = true;
|
||||||
|
} else {
|
||||||
|
getLockMenu().add(new LockAction(c, true));
|
||||||
|
hasUnlocked = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
getLockMenu().setEnabled(hasUnlocked);
|
||||||
|
getUnlockMenu().setEnabled(hasLocked);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ActionFactory.CutAction getCutAction() {
|
||||||
|
if (cutAction == null) {
|
||||||
|
cutAction = ActionFactory.getInstance().createCutAction(plugInPort, clipboard, this);
|
||||||
|
}
|
||||||
|
return cutAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ActionFactory.CopyAction getCopyAction() {
|
||||||
|
if (copyAction == null) {
|
||||||
|
copyAction = ActionFactory.getInstance().createCopyAction(plugInPort, clipboard, this);
|
||||||
|
}
|
||||||
|
return copyAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ActionFactory.PasteAction getPasteAction() {
|
||||||
|
if (pasteAction == null) {
|
||||||
|
pasteAction = ActionFactory.getInstance().createPasteAction(plugInPort, clipboard);
|
||||||
|
}
|
||||||
|
return pasteAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ActionFactory.DuplicateAction getDuplicateAction() {
|
||||||
|
if (duplicateAction == null) {
|
||||||
|
duplicateAction = ActionFactory.getInstance().createDuplicateAction(plugInPort);
|
||||||
|
}
|
||||||
|
return duplicateAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ActionFactory.EditSelectionAction getEditSelectionAction() {
|
||||||
|
if (editSelectionAction == null) {
|
||||||
|
editSelectionAction = ActionFactory.getInstance().createEditSelectionAction(plugInPort);
|
||||||
|
}
|
||||||
|
return editSelectionAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ActionFactory.DeleteSelectionAction getDeleteSelectionAction() {
|
||||||
|
if (deleteSelectionAction == null) {
|
||||||
|
deleteSelectionAction = ActionFactory.getInstance().createDeleteSelectionAction(plugInPort);
|
||||||
|
}
|
||||||
|
return deleteSelectionAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ActionFactory.RotateSelectionAction getRotateClockwiseAction() {
|
||||||
|
if (rotateClockwiseAction == null) {
|
||||||
|
rotateClockwiseAction =
|
||||||
|
ActionFactory.getInstance().createRotateSelectionAction(plugInPort, 1);
|
||||||
|
}
|
||||||
|
return rotateClockwiseAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ActionFactory.RotateSelectionAction getRotateCounterclockwiseAction() {
|
||||||
|
if (rotateCounterclockwiseAction == null) {
|
||||||
|
rotateCounterclockwiseAction =
|
||||||
|
ActionFactory.getInstance().createRotateSelectionAction(plugInPort, -1);
|
||||||
|
}
|
||||||
|
return rotateCounterclockwiseAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ActionFactory.MirrorSelectionAction getMirrorHorizontallyAction() {
|
||||||
|
if (mirrorHorizontallyAction == null) {
|
||||||
|
mirrorHorizontallyAction = ActionFactory.getInstance().createMirrorSelectionAction(plugInPort,
|
||||||
|
IComponentTransformer.HORIZONTAL);
|
||||||
|
}
|
||||||
|
return mirrorHorizontallyAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ActionFactory.MirrorSelectionAction getMirrorVerticallyAction() {
|
||||||
|
if (mirrorVerticallyAction == null) {
|
||||||
|
mirrorVerticallyAction = ActionFactory.getInstance().createMirrorSelectionAction(plugInPort,
|
||||||
|
IComponentTransformer.VERTICAL);
|
||||||
|
}
|
||||||
|
return mirrorVerticallyAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ActionFactory.FlexibleLeadsAction getFlexibleLeadsAction() {
|
||||||
|
if (flexibleLeadsAction == null)
|
||||||
|
flexibleLeadsAction = ActionFactory.getInstance().createFlexibleLeadsAction(plugInPort);
|
||||||
|
return flexibleLeadsAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ActionFactory.SaveAsTemplateAction getSaveAsTemplateAction() {
|
||||||
|
if (saveAsTemplateAction == null) {
|
||||||
|
saveAsTemplateAction = ActionFactory.getInstance().createSaveAsTemplateAction(plugInPort);
|
||||||
|
}
|
||||||
|
return saveAsTemplateAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ActionFactory.SaveAsBlockAction getSaveAsBlockAction() {
|
||||||
|
if (saveAsBlockAction == null) {
|
||||||
|
saveAsBlockAction = ActionFactory.getInstance().createSaveAsBlockAction(plugInPort);
|
||||||
|
}
|
||||||
|
return saveAsBlockAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ActionFactory.GroupAction getGroupAction() {
|
||||||
|
if (groupAction == null) {
|
||||||
|
groupAction = ActionFactory.getInstance().createGroupAction(plugInPort);
|
||||||
|
}
|
||||||
|
return groupAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ActionFactory.UngroupAction getUngroupAction() {
|
||||||
|
if (ungroupAction == null) {
|
||||||
|
ungroupAction = ActionFactory.getInstance().createUngroupAction(plugInPort);
|
||||||
|
}
|
||||||
|
return ungroupAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ActionFactory.SendToBackAction getSendToBackAction() {
|
||||||
|
if (sendToBackAction == null) {
|
||||||
|
sendToBackAction = ActionFactory.getInstance().createSendToBackAction(plugInPort);
|
||||||
|
}
|
||||||
|
return sendToBackAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ActionFactory.BringToFrontAction getBringToFrontAction() {
|
||||||
|
if (bringToFrontAction == null) {
|
||||||
|
bringToFrontAction = ActionFactory.getInstance().createBringToFrontAction(plugInPort);
|
||||||
|
}
|
||||||
|
return bringToFrontAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ActionFactory.NudgeAction getNudgeAction() {
|
||||||
|
if (nudgeAction == null) {
|
||||||
|
nudgeAction = ActionFactory.getInstance().createNudgeAction(plugInPort);
|
||||||
|
}
|
||||||
|
return nudgeAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ActionFactory.ExpandSelectionAction getExpandSelectionAllAction() {
|
||||||
|
if (expandSelectionAllAction == null) {
|
||||||
|
expandSelectionAllAction =
|
||||||
|
ActionFactory.getInstance().createExpandSelectionAction(plugInPort, ExpansionMode.ALL);
|
||||||
|
}
|
||||||
|
return expandSelectionAllAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ActionFactory.ExpandSelectionAction getExpandSelectionImmediateAction() {
|
||||||
|
if (expandSelectionImmediateAction == null) {
|
||||||
|
expandSelectionImmediateAction = ActionFactory.getInstance()
|
||||||
|
.createExpandSelectionAction(plugInPort, ExpansionMode.IMMEDIATE);
|
||||||
|
}
|
||||||
|
return expandSelectionImmediateAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ActionFactory.ExpandSelectionAction getExpandSelectionSameTypeAction() {
|
||||||
|
if (expandSelectionSameTypeAction == null) {
|
||||||
|
expandSelectionSameTypeAction = ActionFactory.getInstance()
|
||||||
|
.createExpandSelectionAction(plugInPort, ExpansionMode.SAME_TYPE);
|
||||||
|
}
|
||||||
|
return expandSelectionSameTypeAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void lostOwnership(Clipboard clipboard, Transferable contents) {
|
||||||
|
LOG.debug("Lost clipboard ownership");
|
||||||
|
}
|
||||||
|
|
||||||
|
class LockAction extends AbstractAction {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private IDIYComponent<?> component;
|
||||||
|
private boolean locked;
|
||||||
|
|
||||||
|
public LockAction(IDIYComponent<?> component, boolean locked) {
|
||||||
|
super();
|
||||||
|
this.locked = locked;
|
||||||
|
this.component = component;
|
||||||
|
putValue(AbstractAction.NAME, component.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
plugInPort.lockComponent(component, locked);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -77,6 +77,7 @@ import org.diylc.swing.plugins.canvas.CanvasPlugin;
|
|||||||
import org.diylc.swing.plugins.cloud.CloudPlugIn;
|
import org.diylc.swing.plugins.cloud.CloudPlugIn;
|
||||||
import org.diylc.swing.plugins.config.ConfigPlugin;
|
import org.diylc.swing.plugins.config.ConfigPlugin;
|
||||||
import org.diylc.swing.plugins.edit.EditMenuPlugin;
|
import org.diylc.swing.plugins.edit.EditMenuPlugin;
|
||||||
|
import org.diylc.swing.plugins.explorer.ExplorerPlugin;
|
||||||
import org.diylc.swing.plugins.file.FileFilterEnum;
|
import org.diylc.swing.plugins.file.FileFilterEnum;
|
||||||
import org.diylc.swing.plugins.file.FileMenuPlugin;
|
import org.diylc.swing.plugins.file.FileMenuPlugin;
|
||||||
import org.diylc.swing.plugins.help.HelpMenuPlugin;
|
import org.diylc.swing.plugins.help.HelpMenuPlugin;
|
||||||
@@ -118,7 +119,7 @@ public class MainFrame extends JFrame implements ISwingUI {
|
|||||||
IconLoader.IconLarge.getImage()));
|
IconLoader.IconLarge.getImage()));
|
||||||
DialogFactory.getInstance().initialize(this);
|
DialogFactory.getInstance().initialize(this);
|
||||||
|
|
||||||
IConfigurationManager configManager = ConfigurationManager.getInstance();
|
IConfigurationManager<?> configManager = ConfigurationManager.getInstance();
|
||||||
|
|
||||||
this.presenter = new Presenter(this, configManager, true);
|
this.presenter = new Presenter(this, configManager, true);
|
||||||
|
|
||||||
@@ -138,6 +139,7 @@ public class MainFrame extends JFrame implements ISwingUI {
|
|||||||
canvasPlugin = new CanvasPlugin(this, configManager);
|
canvasPlugin = new CanvasPlugin(this, configManager);
|
||||||
presenter.installPlugin(() -> canvasPlugin);
|
presenter.installPlugin(() -> canvasPlugin);
|
||||||
presenter.installPlugin(() -> new ComponentTree(this, canvasPlugin.getCanvasPanel()));
|
presenter.installPlugin(() -> new ComponentTree(this, canvasPlugin.getCanvasPanel()));
|
||||||
|
presenter.installPlugin(() -> new ExplorerPlugin(this, canvasPlugin.getCanvasPanel()));
|
||||||
|
|
||||||
presenter.installPlugin(() -> new FramePlugin());
|
presenter.installPlugin(() -> new FramePlugin());
|
||||||
|
|
||||||
@@ -316,10 +318,10 @@ public class MainFrame extends JFrame implements ISwingUI {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void injectGUIComponent(JComponent component, int position, boolean collapsible) throws BadPositionException {
|
public void injectGUIComponent(JComponent component, int position, boolean collapsible, String visibilityConfigKey) throws BadPositionException {
|
||||||
LOG.info(String.format("injectGUIComponent(%s, %s, %s)", component.getClass().getName(), position, collapsible));
|
LOG.info(String.format("injectGUIComponent(%s, %s, %s, %s)", component.getClass().getName(), position, collapsible, visibilityConfigKey));
|
||||||
if (collapsible) {
|
if (collapsible) {
|
||||||
CollapsiblePanel panel = new CollapsiblePanel(position);
|
CollapsiblePanel panel = new CollapsiblePanel(position, visibilityConfigKey);
|
||||||
panel.add(component);
|
panel.add(component);
|
||||||
component = panel;
|
component = panel;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,97 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
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.AlphaComposite;
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Graphics;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.event.FocusAdapter;
|
||||||
|
import java.awt.event.FocusEvent;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import javax.swing.Icon;
|
||||||
|
import javax.swing.JTextField;
|
||||||
|
import javax.swing.event.DocumentEvent;
|
||||||
|
import javax.swing.event.DocumentListener;
|
||||||
|
import org.diylc.swing.images.IconLoader;
|
||||||
|
|
||||||
|
public class SearchTextField extends JTextField {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private boolean supportsQuickJump;
|
||||||
|
private char shortcutKey;
|
||||||
|
|
||||||
|
public SearchTextField(boolean supportsQuickJump, char shortcutKey, Consumer<String> searchAction) {
|
||||||
|
super();
|
||||||
|
this.supportsQuickJump = supportsQuickJump;
|
||||||
|
this.shortcutKey = shortcutKey;
|
||||||
|
|
||||||
|
addFocusListener(new FocusAdapter() {
|
||||||
|
@Override
|
||||||
|
public void focusGained(FocusEvent e) {
|
||||||
|
repaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void focusLost(FocusEvent e) {
|
||||||
|
repaint();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
getDocument().addDocumentListener(new DocumentListener() {
|
||||||
|
|
||||||
|
public void changedUpdate(DocumentEvent e) {
|
||||||
|
process();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeUpdate(DocumentEvent e) {
|
||||||
|
process();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void insertUpdate(DocumentEvent e) {
|
||||||
|
process();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void process() {
|
||||||
|
String text = getText();
|
||||||
|
searchAction.accept(text);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void paint(Graphics g) {
|
||||||
|
super.paint(g);
|
||||||
|
|
||||||
|
Graphics2D g2d = (Graphics2D) g;
|
||||||
|
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f));
|
||||||
|
Icon icon = IconLoader.SearchBox.getIcon();
|
||||||
|
icon.paintIcon(this, g2d, this.getWidth() - 18, 3);
|
||||||
|
|
||||||
|
if (this.getText().trim().length() == 0 && !this.hasFocus()) {
|
||||||
|
g2d.setColor(Color.gray);
|
||||||
|
g2d.setFont(this.getFont());
|
||||||
|
g2d.drawString(supportsQuickJump ? "Search (press " + shortcutKey + " to jump here)" : "Search", 4, 3 + this.getFont().getSize());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -195,7 +195,7 @@ public class ActionBarPlugin implements IPlugIn {
|
|||||||
this.plugInPort = plugInPort;
|
this.plugInPort = plugInPort;
|
||||||
if (Utils.isMac()) {
|
if (Utils.isMac()) {
|
||||||
try {
|
try {
|
||||||
swingUI.injectGUIComponent(getActionPanel(), SwingConstants.CENTER, false);
|
swingUI.injectGUIComponent(getActionPanel(), SwingConstants.CENTER, false, null);
|
||||||
} catch (BadPositionException e) {
|
} catch (BadPositionException e) {
|
||||||
LOG.error("Could not inject action bar plugin", e);
|
LOG.error("Could not inject action bar plugin", e);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,16 +17,10 @@
|
|||||||
*/
|
*/
|
||||||
package org.diylc.swing.plugins.canvas;
|
package org.diylc.swing.plugins.canvas;
|
||||||
|
|
||||||
import java.awt.Component;
|
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
import java.awt.Point;
|
import java.awt.Point;
|
||||||
import java.awt.Rectangle;
|
import java.awt.Rectangle;
|
||||||
import java.awt.Toolkit;
|
|
||||||
import java.awt.datatransfer.Clipboard;
|
|
||||||
import java.awt.datatransfer.ClipboardOwner;
|
|
||||||
import java.awt.datatransfer.Transferable;
|
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.awt.event.ActionListener;
|
|
||||||
import java.awt.event.AdjustmentEvent;
|
import java.awt.event.AdjustmentEvent;
|
||||||
import java.awt.event.AdjustmentListener;
|
import java.awt.event.AdjustmentListener;
|
||||||
import java.awt.event.KeyAdapter;
|
import java.awt.event.KeyAdapter;
|
||||||
@@ -37,14 +31,8 @@ import java.awt.event.MouseWheelEvent;
|
|||||||
import java.awt.event.MouseWheelListener;
|
import java.awt.event.MouseWheelListener;
|
||||||
import java.awt.geom.Point2D;
|
import java.awt.geom.Point2D;
|
||||||
import java.awt.geom.Rectangle2D;
|
import java.awt.geom.Rectangle2D;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
import java.util.List;
|
|
||||||
import javax.swing.AbstractAction;
|
import javax.swing.AbstractAction;
|
||||||
import javax.swing.JMenu;
|
|
||||||
import javax.swing.JMenuItem;
|
|
||||||
import javax.swing.JPopupMenu;
|
|
||||||
import javax.swing.JScrollBar;
|
import javax.swing.JScrollBar;
|
||||||
import javax.swing.JScrollPane;
|
import javax.swing.JScrollPane;
|
||||||
import javax.swing.SwingConstants;
|
import javax.swing.SwingConstants;
|
||||||
@@ -53,26 +41,17 @@ import org.apache.log4j.Logger;
|
|||||||
import org.diylc.appframework.miscutils.IConfigListener;
|
import org.diylc.appframework.miscutils.IConfigListener;
|
||||||
import org.diylc.appframework.miscutils.IConfigurationManager;
|
import org.diylc.appframework.miscutils.IConfigurationManager;
|
||||||
import org.diylc.appframework.miscutils.Utils;
|
import org.diylc.appframework.miscutils.Utils;
|
||||||
import org.diylc.clipboard.ComponentTransferable;
|
|
||||||
import org.diylc.common.BadPositionException;
|
import org.diylc.common.BadPositionException;
|
||||||
import org.diylc.common.ComponentType;
|
|
||||||
import org.diylc.common.EventType;
|
import org.diylc.common.EventType;
|
||||||
import org.diylc.common.IComponentTransformer;
|
|
||||||
import org.diylc.common.IPlugIn;
|
import org.diylc.common.IPlugIn;
|
||||||
import org.diylc.common.IPlugInPort;
|
import org.diylc.common.IPlugInPort;
|
||||||
import org.diylc.core.ExpansionMode;
|
|
||||||
import org.diylc.core.IDIYComponent;
|
import org.diylc.core.IDIYComponent;
|
||||||
import org.diylc.core.Template;
|
|
||||||
import org.diylc.core.measures.Size;
|
import org.diylc.core.measures.Size;
|
||||||
import org.diylc.core.measures.SizeUnit;
|
import org.diylc.core.measures.SizeUnit;
|
||||||
import org.diylc.presenter.Presenter;
|
import org.diylc.presenter.Presenter;
|
||||||
import org.diylc.swing.ActionFactory;
|
|
||||||
import org.diylc.swing.ISwingUI;
|
import org.diylc.swing.ISwingUI;
|
||||||
import org.diylc.swing.gui.TranslatedMenu;
|
import org.diylc.swing.gui.ComponentPopupMenu;
|
||||||
import org.diylc.swing.gui.TranslatedPopupMenu;
|
|
||||||
import org.diylc.swing.images.IconLoader;
|
|
||||||
import org.diylc.swing.plugins.file.ProjectDrawingProvider;
|
import org.diylc.swing.plugins.file.ProjectDrawingProvider;
|
||||||
import org.diylc.swing.plugins.toolbox.ComponentButtonFactory;
|
|
||||||
import org.diylc.swingframework.ruler.IRulerListener;
|
import org.diylc.swingframework.ruler.IRulerListener;
|
||||||
import org.diylc.swingframework.ruler.Ruler.InchSubdivision;
|
import org.diylc.swingframework.ruler.Ruler.InchSubdivision;
|
||||||
import org.diylc.swingframework.ruler.RulerScrollPane;
|
import org.diylc.swingframework.ruler.RulerScrollPane;
|
||||||
@@ -81,48 +60,17 @@ import com.guigarage.gestures.GestureMagnificationListener;
|
|||||||
import com.guigarage.gestures.GestureUtilities;
|
import com.guigarage.gestures.GestureUtilities;
|
||||||
import com.guigarage.gestures.GesturesNotSupportedException;
|
import com.guigarage.gestures.GesturesNotSupportedException;
|
||||||
|
|
||||||
public class CanvasPlugin implements IPlugIn, ClipboardOwner {
|
public class CanvasPlugin implements IPlugIn{
|
||||||
|
|
||||||
private static final Logger LOG = Logger.getLogger(CanvasPlugin.class);
|
private static final Logger LOG = Logger.getLogger(CanvasPlugin.class);
|
||||||
|
|
||||||
private RulerScrollPane scrollPane;
|
private RulerScrollPane scrollPane;
|
||||||
private CanvasPanel canvasPanel;
|
private CanvasPanel canvasPanel;
|
||||||
private JPopupMenu popupMenu;
|
private ComponentPopupMenu popupMenu;
|
||||||
private JMenu selectionMenu;
|
|
||||||
private JMenu expandMenu;
|
|
||||||
private JMenu transformMenu;
|
|
||||||
private JMenu applyTemplateMenu;
|
|
||||||
private JMenu applyModelMenu;
|
|
||||||
private JMenu lockMenu;
|
|
||||||
private JMenu unlockMenu;
|
|
||||||
|
|
||||||
private ActionFactory.CutAction cutAction;
|
|
||||||
private ActionFactory.CopyAction copyAction;
|
|
||||||
private ActionFactory.PasteAction pasteAction;
|
|
||||||
private ActionFactory.DuplicateAction duplicateAction;
|
|
||||||
private ActionFactory.EditSelectionAction editSelectionAction;
|
|
||||||
private ActionFactory.DeleteSelectionAction deleteSelectionAction;
|
|
||||||
private ActionFactory.SaveAsTemplateAction saveAsTemplateAction;
|
|
||||||
private ActionFactory.SaveAsBlockAction saveAsBlockAction;
|
|
||||||
private ActionFactory.GroupAction groupAction;
|
|
||||||
private ActionFactory.UngroupAction ungroupAction;
|
|
||||||
private ActionFactory.SendToBackAction sendToBackAction;
|
|
||||||
private ActionFactory.BringToFrontAction bringToFrontAction;
|
|
||||||
private ActionFactory.NudgeAction nudgeAction;
|
|
||||||
private ActionFactory.ExpandSelectionAction expandSelectionAllAction;
|
|
||||||
private ActionFactory.ExpandSelectionAction expandSelectionImmediateAction;
|
|
||||||
private ActionFactory.ExpandSelectionAction expandSelectionSameTypeAction;
|
|
||||||
private ActionFactory.RotateSelectionAction rotateClockwiseAction;
|
|
||||||
private ActionFactory.RotateSelectionAction rotateCounterclockwiseAction;
|
|
||||||
private ActionFactory.MirrorSelectionAction mirrorHorizontallyAction;
|
|
||||||
private ActionFactory.MirrorSelectionAction mirrorVerticallyAction;
|
|
||||||
private ActionFactory.FlexibleLeadsAction flexibleLeadsAction;
|
|
||||||
|
|
||||||
private IPlugInPort plugInPort;
|
private IPlugInPort plugInPort;
|
||||||
private ISwingUI swingUI;
|
private ISwingUI swingUI;
|
||||||
|
|
||||||
private Clipboard clipboard;
|
|
||||||
|
|
||||||
private double zoomLevel = 1;
|
private double zoomLevel = 1;
|
||||||
|
|
||||||
private IConfigurationManager<?> configManager;
|
private IConfigurationManager<?> configManager;
|
||||||
@@ -130,7 +78,6 @@ public class CanvasPlugin implements IPlugIn, ClipboardOwner {
|
|||||||
public CanvasPlugin(ISwingUI swingUI, IConfigurationManager<?> configManager) {
|
public CanvasPlugin(ISwingUI swingUI, IConfigurationManager<?> configManager) {
|
||||||
this.swingUI = swingUI;
|
this.swingUI = swingUI;
|
||||||
this.configManager = configManager;
|
this.configManager = configManager;
|
||||||
clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -152,7 +99,7 @@ public class CanvasPlugin implements IPlugIn, ClipboardOwner {
|
|||||||
public void connect(IPlugInPort plugInPort) {
|
public void connect(IPlugInPort plugInPort) {
|
||||||
this.plugInPort = plugInPort;
|
this.plugInPort = plugInPort;
|
||||||
try {
|
try {
|
||||||
swingUI.injectGUIComponent(getScrollPane(), SwingConstants.CENTER, false);
|
swingUI.injectGUIComponent(getScrollPane(), SwingConstants.CENTER, false, null);
|
||||||
} catch (BadPositionException e) {
|
} catch (BadPositionException e) {
|
||||||
LOG.error("Could not install canvas plugin", e);
|
LOG.error("Could not install canvas plugin", e);
|
||||||
}
|
}
|
||||||
@@ -285,38 +232,11 @@ public class CanvasPlugin implements IPlugIn, ClipboardOwner {
|
|||||||
public void run() {
|
public void run() {
|
||||||
if (plugInPort.getNewComponentTypeSlot() == null && (e.isPopupTrigger()
|
if (plugInPort.getNewComponentTypeSlot() == null && (e.isPopupTrigger()
|
||||||
|| (pressedEvent != null && pressedEvent.isPopupTrigger()))) {
|
|| (pressedEvent != null && pressedEvent.isPopupTrigger()))) {
|
||||||
// Enable actions.
|
|
||||||
boolean enabled = !plugInPort.getSelectedComponents().isEmpty();
|
|
||||||
getCutAction().setEnabled(enabled);
|
|
||||||
getCopyAction().setEnabled(enabled);
|
|
||||||
getDuplicateAction().setEnabled(enabled);
|
|
||||||
try {
|
|
||||||
getPasteAction().setEnabled(
|
|
||||||
clipboard.isDataFlavorAvailable(ComponentTransferable.listFlavor));
|
|
||||||
} catch (Exception ex) {
|
|
||||||
getPasteAction().setEnabled(false);
|
|
||||||
}
|
|
||||||
getEditSelectionAction().setEnabled(enabled);
|
|
||||||
getDeleteSelectionAction().setEnabled(enabled);
|
|
||||||
getExpandSelectionAllAction().setEnabled(enabled);
|
|
||||||
getExpandSelectionImmediateAction().setEnabled(enabled);
|
|
||||||
getExpandSelectionSameTypeAction().setEnabled(enabled);
|
|
||||||
getGroupAction().setEnabled(enabled);
|
|
||||||
getUngroupAction().setEnabled(enabled);
|
|
||||||
getNudgeAction().setEnabled(enabled);
|
|
||||||
getSendToBackAction().setEnabled(enabled);
|
|
||||||
getBringToFrontAction().setEnabled(enabled);
|
|
||||||
getRotateClockwiseAction().setEnabled(enabled);
|
|
||||||
getRotateCounterclockwiseAction().setEnabled(enabled);
|
|
||||||
getMirrorHorizontallyAction().setEnabled(enabled);
|
|
||||||
getMirrorVerticallyAction().setEnabled(enabled);
|
|
||||||
getFlexibleLeadsAction().setEnabled(enabled);
|
|
||||||
|
|
||||||
getSaveAsTemplateAction()
|
int x = e.getX();
|
||||||
.setEnabled(plugInPort.getSelectedComponents().size() == 1);
|
int y = e.getY();
|
||||||
getSaveAsBlockAction().setEnabled(plugInPort.getSelectedComponents().size() > 1);
|
getPopupMenu().prepareAndShowAt(plugInPort.findComponentsAt(new Point(x, y), false),
|
||||||
|
plugInPort.findComponentsAt(new Point(x, y), true), x, y);
|
||||||
showPopupAt(e.getX(), e.getY());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -521,371 +441,13 @@ public class CanvasPlugin implements IPlugIn, ClipboardOwner {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showPopupAt(int x, int y) {
|
public ComponentPopupMenu getPopupMenu() {
|
||||||
updateSelectionMenu(x, y);
|
|
||||||
updateApplyTemplateMenu();
|
|
||||||
updateApplyModelMenu();
|
|
||||||
updateLock(x, y);
|
|
||||||
getPopupMenu().show(canvasPanel, x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
public JPopupMenu getPopupMenu() {
|
|
||||||
if (popupMenu == null) {
|
if (popupMenu == null) {
|
||||||
popupMenu = new TranslatedPopupMenu();
|
popupMenu = new ComponentPopupMenu(plugInPort, canvasPanel, true);
|
||||||
popupMenu.add(getSelectionMenu());
|
|
||||||
popupMenu.addSeparator();
|
|
||||||
popupMenu.add(getCutAction());
|
|
||||||
popupMenu.add(getCopyAction());
|
|
||||||
popupMenu.add(getPasteAction());
|
|
||||||
popupMenu.add(getDuplicateAction());
|
|
||||||
popupMenu.addSeparator();
|
|
||||||
popupMenu.add(getEditSelectionAction());
|
|
||||||
popupMenu.add(getDeleteSelectionAction());
|
|
||||||
popupMenu.add(getTransformMenu());
|
|
||||||
popupMenu.add(getSaveAsTemplateAction());
|
|
||||||
popupMenu.add(getApplyTemplateMenu());
|
|
||||||
popupMenu.add(getApplyModelMenu());
|
|
||||||
popupMenu.add(getSaveAsBlockAction());
|
|
||||||
popupMenu.add(getExpandMenu());
|
|
||||||
popupMenu.addSeparator();
|
|
||||||
popupMenu.add(getLockMenu());
|
|
||||||
popupMenu.add(getUnlockMenu());
|
|
||||||
popupMenu.addSeparator();
|
|
||||||
popupMenu.add(getFlexibleLeadsAction());
|
|
||||||
popupMenu.addSeparator();
|
|
||||||
popupMenu.add(ActionFactory.getInstance().createEditProjectAction(plugInPort));
|
|
||||||
}
|
}
|
||||||
return popupMenu;
|
return popupMenu;
|
||||||
}
|
}
|
||||||
|
|
||||||
public JMenu getSelectionMenu() {
|
|
||||||
if (selectionMenu == null) {
|
|
||||||
selectionMenu = new TranslatedMenu("Select");
|
|
||||||
selectionMenu.setIcon(IconLoader.ElementsSelection.getIcon());
|
|
||||||
}
|
|
||||||
return selectionMenu;
|
|
||||||
}
|
|
||||||
|
|
||||||
public JMenu getExpandMenu() {
|
|
||||||
if (expandMenu == null) {
|
|
||||||
expandMenu = new TranslatedMenu("Expand Selection");
|
|
||||||
expandMenu.setIcon(IconLoader.BranchAdd.getIcon());
|
|
||||||
expandMenu.add(getExpandSelectionAllAction());
|
|
||||||
expandMenu.add(getExpandSelectionImmediateAction());
|
|
||||||
expandMenu.add(getExpandSelectionSameTypeAction());
|
|
||||||
}
|
|
||||||
return expandMenu;
|
|
||||||
}
|
|
||||||
|
|
||||||
public JMenu getLockMenu() {
|
|
||||||
if (lockMenu == null) {
|
|
||||||
lockMenu = new TranslatedMenu("Lock");
|
|
||||||
lockMenu.setIcon(IconLoader.Lock.getIcon());
|
|
||||||
}
|
|
||||||
return lockMenu;
|
|
||||||
}
|
|
||||||
|
|
||||||
public JMenu getUnlockMenu() {
|
|
||||||
if (unlockMenu == null) {
|
|
||||||
unlockMenu = new TranslatedMenu("Unlock");
|
|
||||||
unlockMenu.setIcon(IconLoader.Unlock.getIcon());
|
|
||||||
}
|
|
||||||
return unlockMenu;
|
|
||||||
}
|
|
||||||
|
|
||||||
public JMenu getTransformMenu() {
|
|
||||||
if (transformMenu == null) {
|
|
||||||
transformMenu = new TranslatedMenu("Transform Selection");
|
|
||||||
transformMenu.setIcon(IconLoader.MagicWand.getIcon());
|
|
||||||
transformMenu.add(getRotateClockwiseAction());
|
|
||||||
transformMenu.add(getRotateCounterclockwiseAction());
|
|
||||||
transformMenu.addSeparator();
|
|
||||||
transformMenu.add(getMirrorHorizontallyAction());
|
|
||||||
transformMenu.add(getMirrorVerticallyAction());
|
|
||||||
transformMenu.addSeparator();
|
|
||||||
transformMenu.add(getNudgeAction());
|
|
||||||
transformMenu.addSeparator();
|
|
||||||
transformMenu.add(getSendToBackAction());
|
|
||||||
transformMenu.add(getBringToFrontAction());
|
|
||||||
transformMenu.addSeparator();
|
|
||||||
transformMenu.add(getGroupAction());
|
|
||||||
transformMenu.add(getUngroupAction());
|
|
||||||
}
|
|
||||||
return transformMenu;
|
|
||||||
}
|
|
||||||
|
|
||||||
public JMenu getApplyTemplateMenu() {
|
|
||||||
if (applyTemplateMenu == null) {
|
|
||||||
applyTemplateMenu = new TranslatedMenu("Apply Variant");
|
|
||||||
applyTemplateMenu.setIcon(IconLoader.BriefcaseInto.getIcon());
|
|
||||||
}
|
|
||||||
return applyTemplateMenu;
|
|
||||||
}
|
|
||||||
|
|
||||||
public JMenu getApplyModelMenu() {
|
|
||||||
if (applyModelMenu == null) {
|
|
||||||
applyModelMenu = new TranslatedMenu("Apply Model");
|
|
||||||
applyModelMenu.setIcon(IconLoader.Barcode.getIcon());
|
|
||||||
}
|
|
||||||
return applyModelMenu;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateSelectionMenu(int x, int y) {
|
|
||||||
getSelectionMenu().removeAll();
|
|
||||||
for (IDIYComponent<?> component : plugInPort.findComponentsAt(new Point(x, y), false)) {
|
|
||||||
JMenuItem item = new JMenuItem(component.getName());
|
|
||||||
final IDIYComponent<?> finalComponent = component;
|
|
||||||
item.addActionListener(new ActionListener() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(ActionEvent e) {
|
|
||||||
List<IDIYComponent<?>> newSelection = new ArrayList<IDIYComponent<?>>();
|
|
||||||
newSelection.add(finalComponent);
|
|
||||||
plugInPort.updateSelection(newSelection);
|
|
||||||
plugInPort.refresh();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
getSelectionMenu().add(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateLock(int x, int y) {
|
|
||||||
getLockMenu().removeAll();
|
|
||||||
getUnlockMenu().removeAll();
|
|
||||||
List<IDIYComponent<?>> componentsAt = plugInPort.findComponentsAt(new Point(x, y), true);
|
|
||||||
if (componentsAt.size() == 0) {
|
|
||||||
getLockMenu().setEnabled(false);
|
|
||||||
getUnlockMenu().setEnabled(false);
|
|
||||||
} else {
|
|
||||||
boolean hasLocked = false;
|
|
||||||
boolean hasUnlocked = false;
|
|
||||||
for (IDIYComponent<?> c : componentsAt) {
|
|
||||||
if (plugInPort.getCurrentProject().getLockedComponents().contains(c)) {
|
|
||||||
getUnlockMenu().add(new LockAction(c, false));
|
|
||||||
hasLocked = true;
|
|
||||||
} else {
|
|
||||||
getLockMenu().add(new LockAction(c, true));
|
|
||||||
hasUnlocked = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
getLockMenu().setEnabled(hasUnlocked);
|
|
||||||
getUnlockMenu().setEnabled(hasLocked);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateApplyTemplateMenu() {
|
|
||||||
JMenu applyMenu = getApplyTemplateMenu();
|
|
||||||
applyMenu.removeAll();
|
|
||||||
List<Template> templates = null;
|
|
||||||
|
|
||||||
try {
|
|
||||||
templates = plugInPort.getVariantsForSelection();
|
|
||||||
} catch (Exception e) {
|
|
||||||
LOG.info("Could not load variants for selection");
|
|
||||||
applyMenu.setEnabled(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (templates == null) {
|
|
||||||
applyMenu.setEnabled(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
applyMenu.setEnabled(templates.size() > 0);
|
|
||||||
|
|
||||||
for (Template template : templates) {
|
|
||||||
JMenuItem item = new JMenuItem(template.getName());
|
|
||||||
final Template finalTemplate = template;
|
|
||||||
item.addActionListener(new ActionListener() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(ActionEvent e) {
|
|
||||||
plugInPort.applyVariantToSelection(finalTemplate);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
applyMenu.add(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateApplyModelMenu() {
|
|
||||||
JMenu applyMenu = getApplyModelMenu();
|
|
||||||
applyMenu.removeAll();
|
|
||||||
|
|
||||||
Collection<ComponentType> selectedComponentTypes = plugInPort.getSelectedComponentTypes();
|
|
||||||
if (selectedComponentTypes.size() != 1) {
|
|
||||||
applyMenu.setEnabled(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ComponentType componentType = selectedComponentTypes.stream().findFirst().get();
|
|
||||||
List<String[]> datasheet = componentType.getDatasheet();
|
|
||||||
if (datasheet == null || datasheet.isEmpty()) {
|
|
||||||
applyMenu.setEnabled(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
applyMenu.setEnabled(true);
|
|
||||||
List<Component> datasheetItems = ComponentButtonFactory.createDatasheetItems(plugInPort, componentType, new ArrayList<String>(), model -> {
|
|
||||||
LOG.info("Applying datasheet model " + String.join(", ", model));
|
|
||||||
plugInPort.applyModelToSelection(model);
|
|
||||||
});
|
|
||||||
for (Component item : datasheetItems) {
|
|
||||||
applyMenu.add(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public ActionFactory.CutAction getCutAction() {
|
|
||||||
if (cutAction == null) {
|
|
||||||
cutAction = ActionFactory.getInstance().createCutAction(plugInPort, clipboard, this);
|
|
||||||
}
|
|
||||||
return cutAction;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ActionFactory.CopyAction getCopyAction() {
|
|
||||||
if (copyAction == null) {
|
|
||||||
copyAction = ActionFactory.getInstance().createCopyAction(plugInPort, clipboard, this);
|
|
||||||
}
|
|
||||||
return copyAction;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ActionFactory.PasteAction getPasteAction() {
|
|
||||||
if (pasteAction == null) {
|
|
||||||
pasteAction = ActionFactory.getInstance().createPasteAction(plugInPort, clipboard);
|
|
||||||
}
|
|
||||||
return pasteAction;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ActionFactory.DuplicateAction getDuplicateAction() {
|
|
||||||
if (duplicateAction == null) {
|
|
||||||
duplicateAction = ActionFactory.getInstance().createDuplicateAction(plugInPort);
|
|
||||||
}
|
|
||||||
return duplicateAction;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ActionFactory.EditSelectionAction getEditSelectionAction() {
|
|
||||||
if (editSelectionAction == null) {
|
|
||||||
editSelectionAction = ActionFactory.getInstance().createEditSelectionAction(plugInPort);
|
|
||||||
}
|
|
||||||
return editSelectionAction;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ActionFactory.DeleteSelectionAction getDeleteSelectionAction() {
|
|
||||||
if (deleteSelectionAction == null) {
|
|
||||||
deleteSelectionAction = ActionFactory.getInstance().createDeleteSelectionAction(plugInPort);
|
|
||||||
}
|
|
||||||
return deleteSelectionAction;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ActionFactory.RotateSelectionAction getRotateClockwiseAction() {
|
|
||||||
if (rotateClockwiseAction == null) {
|
|
||||||
rotateClockwiseAction =
|
|
||||||
ActionFactory.getInstance().createRotateSelectionAction(plugInPort, 1);
|
|
||||||
}
|
|
||||||
return rotateClockwiseAction;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ActionFactory.RotateSelectionAction getRotateCounterclockwiseAction() {
|
|
||||||
if (rotateCounterclockwiseAction == null) {
|
|
||||||
rotateCounterclockwiseAction =
|
|
||||||
ActionFactory.getInstance().createRotateSelectionAction(plugInPort, -1);
|
|
||||||
}
|
|
||||||
return rotateCounterclockwiseAction;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ActionFactory.MirrorSelectionAction getMirrorHorizontallyAction() {
|
|
||||||
if (mirrorHorizontallyAction == null) {
|
|
||||||
mirrorHorizontallyAction = ActionFactory.getInstance().createMirrorSelectionAction(plugInPort,
|
|
||||||
IComponentTransformer.HORIZONTAL);
|
|
||||||
}
|
|
||||||
return mirrorHorizontallyAction;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ActionFactory.MirrorSelectionAction getMirrorVerticallyAction() {
|
|
||||||
if (mirrorVerticallyAction == null) {
|
|
||||||
mirrorVerticallyAction = ActionFactory.getInstance().createMirrorSelectionAction(plugInPort,
|
|
||||||
IComponentTransformer.VERTICAL);
|
|
||||||
}
|
|
||||||
return mirrorVerticallyAction;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ActionFactory.FlexibleLeadsAction getFlexibleLeadsAction() {
|
|
||||||
if (flexibleLeadsAction == null)
|
|
||||||
flexibleLeadsAction = ActionFactory.getInstance().createFlexibleLeadsAction(plugInPort);
|
|
||||||
return flexibleLeadsAction;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ActionFactory.SaveAsTemplateAction getSaveAsTemplateAction() {
|
|
||||||
if (saveAsTemplateAction == null) {
|
|
||||||
saveAsTemplateAction = ActionFactory.getInstance().createSaveAsTemplateAction(plugInPort);
|
|
||||||
}
|
|
||||||
return saveAsTemplateAction;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ActionFactory.SaveAsBlockAction getSaveAsBlockAction() {
|
|
||||||
if (saveAsBlockAction == null) {
|
|
||||||
saveAsBlockAction = ActionFactory.getInstance().createSaveAsBlockAction(plugInPort);
|
|
||||||
}
|
|
||||||
return saveAsBlockAction;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ActionFactory.GroupAction getGroupAction() {
|
|
||||||
if (groupAction == null) {
|
|
||||||
groupAction = ActionFactory.getInstance().createGroupAction(plugInPort);
|
|
||||||
}
|
|
||||||
return groupAction;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ActionFactory.UngroupAction getUngroupAction() {
|
|
||||||
if (ungroupAction == null) {
|
|
||||||
ungroupAction = ActionFactory.getInstance().createUngroupAction(plugInPort);
|
|
||||||
}
|
|
||||||
return ungroupAction;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ActionFactory.SendToBackAction getSendToBackAction() {
|
|
||||||
if (sendToBackAction == null) {
|
|
||||||
sendToBackAction = ActionFactory.getInstance().createSendToBackAction(plugInPort);
|
|
||||||
}
|
|
||||||
return sendToBackAction;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ActionFactory.BringToFrontAction getBringToFrontAction() {
|
|
||||||
if (bringToFrontAction == null) {
|
|
||||||
bringToFrontAction = ActionFactory.getInstance().createBringToFrontAction(plugInPort);
|
|
||||||
}
|
|
||||||
return bringToFrontAction;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ActionFactory.NudgeAction getNudgeAction() {
|
|
||||||
if (nudgeAction == null) {
|
|
||||||
nudgeAction = ActionFactory.getInstance().createNudgeAction(plugInPort);
|
|
||||||
}
|
|
||||||
return nudgeAction;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ActionFactory.ExpandSelectionAction getExpandSelectionAllAction() {
|
|
||||||
if (expandSelectionAllAction == null) {
|
|
||||||
expandSelectionAllAction =
|
|
||||||
ActionFactory.getInstance().createExpandSelectionAction(plugInPort, ExpansionMode.ALL);
|
|
||||||
}
|
|
||||||
return expandSelectionAllAction;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ActionFactory.ExpandSelectionAction getExpandSelectionImmediateAction() {
|
|
||||||
if (expandSelectionImmediateAction == null) {
|
|
||||||
expandSelectionImmediateAction = ActionFactory.getInstance()
|
|
||||||
.createExpandSelectionAction(plugInPort, ExpansionMode.IMMEDIATE);
|
|
||||||
}
|
|
||||||
return expandSelectionImmediateAction;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ActionFactory.ExpandSelectionAction getExpandSelectionSameTypeAction() {
|
|
||||||
if (expandSelectionSameTypeAction == null) {
|
|
||||||
expandSelectionSameTypeAction = ActionFactory.getInstance()
|
|
||||||
.createExpandSelectionAction(plugInPort, ExpansionMode.SAME_TYPE);
|
|
||||||
}
|
|
||||||
return expandSelectionSameTypeAction;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public EnumSet<EventType> getSubscribedEventTypes() {
|
public EnumSet<EventType> getSubscribedEventTypes() {
|
||||||
return EnumSet.of(EventType.PROJECT_LOADED, EventType.ZOOM_CHANGED, EventType.REPAINT,
|
return EnumSet.of(EventType.PROJECT_LOADED, EventType.ZOOM_CHANGED, EventType.REPAINT,
|
||||||
@@ -899,14 +461,16 @@ public class CanvasPlugin implements IPlugIn, ClipboardOwner {
|
|||||||
case PROJECT_LOADED:
|
case PROJECT_LOADED:
|
||||||
refreshSize();
|
refreshSize();
|
||||||
if ((Boolean) params[1]) {
|
if ((Boolean) params[1]) {
|
||||||
// Scroll to the center.
|
|
||||||
final Rectangle visibleRect = canvasPanel.getVisibleRect();
|
|
||||||
visibleRect.setLocation((canvasPanel.getWidth() - visibleRect.width) / 2,
|
|
||||||
(canvasPanel.getHeight() - visibleRect.height) / 2);
|
|
||||||
SwingUtilities.invokeLater(new Runnable() {
|
SwingUtilities.invokeLater(new Runnable() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
// Scroll to the center.
|
||||||
|
final Rectangle visibleRect = canvasPanel.getVisibleRect();
|
||||||
|
visibleRect.setLocation((canvasPanel.getWidth() - visibleRect.width) / 2,
|
||||||
|
(canvasPanel.getHeight() - visibleRect.height) / 2);
|
||||||
|
|
||||||
canvasPanel.scrollRectToVisible(visibleRect);
|
canvasPanel.scrollRectToVisible(visibleRect);
|
||||||
canvasPanel.revalidate();
|
canvasPanel.revalidate();
|
||||||
}
|
}
|
||||||
@@ -937,6 +501,16 @@ public class CanvasPlugin implements IPlugIn, ClipboardOwner {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
if (params.length > 0 && Boolean.TRUE.equals(params[0])) {
|
||||||
|
Rectangle2D selectionBounds = plugInPort.getSelectionBounds(true);
|
||||||
|
if (selectionBounds != null) {
|
||||||
|
Rectangle visibleRect = scrollPane.getVisibleRect();
|
||||||
|
scrollPane.getViewport().setViewPosition(new Point(
|
||||||
|
(int)(selectionBounds.getCenterX() - visibleRect.getWidth() / 2),
|
||||||
|
(int)(selectionBounds.getCenterY() - visibleRect.getHeight() / 2))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (configManager.readBoolean(IPlugInPort.SHOW_RULERS_KEY, true))
|
if (configManager.readBoolean(IPlugInPort.SHOW_RULERS_KEY, true))
|
||||||
scrollPane.setSelectionRectangle(plugInPort.getSelectionBounds(true));
|
scrollPane.setSelectionRectangle(plugInPort.getSelectionBounds(true));
|
||||||
}
|
}
|
||||||
@@ -977,12 +551,6 @@ public class CanvasPlugin implements IPlugIn, ClipboardOwner {
|
|||||||
canvasPanel.dispatchEvent(event);
|
canvasPanel.dispatchEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void lostOwnership(Clipboard clipboard, Transferable contents) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateZeroLocation() {
|
private void updateZeroLocation() {
|
||||||
double extraSpace = CanvasPlugin.this.plugInPort.getExtraSpace();
|
double extraSpace = CanvasPlugin.this.plugInPort.getExtraSpace();
|
||||||
getScrollPane().setZeroLocation(new Point2D.Double(extraSpace, extraSpace));
|
getScrollPane().setZeroLocation(new Point2D.Double(extraSpace, extraSpace));
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ public class ConfigPlugin implements IPlugIn {
|
|||||||
private static final String SNAP_MENU = "Snap To";
|
private static final String SNAP_MENU = "Snap To";
|
||||||
private static final String COMPONENT_BROWSER_MENU = "Toolbox";
|
private static final String COMPONENT_BROWSER_MENU = "Toolbox";
|
||||||
public static final String COMPONENT_BROWSER = "componentBrowser";
|
public static final String COMPONENT_BROWSER = "componentBrowser";
|
||||||
|
public static final String PROJECT_EXPLORER = "projectExplorer";
|
||||||
public static final String SEARCHABLE_TREE = "Searchable Tree";
|
public static final String SEARCHABLE_TREE = "Searchable Tree";
|
||||||
public static final String TABBED_TOOLBAR = "Tabbed Toolbar";
|
public static final String TABBED_TOOLBAR = "Tabbed Toolbar";
|
||||||
private static final String LANGUAGE_MENU = LangUtil.translate("Language");
|
private static final String LANGUAGE_MENU = LangUtil.translate("Language");
|
||||||
@@ -140,6 +141,10 @@ public class ConfigPlugin implements IPlugIn {
|
|||||||
ActionFactory.getInstance().createToggleAction(IPlugInPort.RULER_IN_SUBDIVISION_2, IPlugInPort.RULER_IN_SUBDIVISION_KEY, RULER_MENU, IPlugInPort.RULER_IN_SUBDIVISION_DEFAULT),
|
ActionFactory.getInstance().createToggleAction(IPlugInPort.RULER_IN_SUBDIVISION_2, IPlugInPort.RULER_IN_SUBDIVISION_KEY, RULER_MENU, IPlugInPort.RULER_IN_SUBDIVISION_DEFAULT),
|
||||||
RULER_MENU);
|
RULER_MENU);
|
||||||
|
|
||||||
|
swingUI.injectMenuAction(
|
||||||
|
ActionFactory.getInstance().createConfigAction(plugInPort, "Show Project Explorer",
|
||||||
|
ConfigPlugin.PROJECT_EXPLORER, true), CONFIG_MENU);
|
||||||
|
|
||||||
swingUI.injectMenuAction(
|
swingUI.injectMenuAction(
|
||||||
ActionFactory.getInstance().createConfigAction(plugInPort, "Show Rulers", IPlugInPort.SHOW_RULERS_KEY, true),
|
ActionFactory.getInstance().createConfigAction(plugInPort, "Show Rulers", IPlugInPort.SHOW_RULERS_KEY, true),
|
||||||
CONFIG_MENU);
|
CONFIG_MENU);
|
||||||
|
|||||||
@@ -339,7 +339,7 @@ public class EditMenuPlugin implements IPlugIn, ClipboardOwner {
|
|||||||
refreshActions();
|
refreshActions();
|
||||||
break;
|
break;
|
||||||
case PROJECT_MODIFIED:
|
case PROJECT_MODIFIED:
|
||||||
undoHandler.stateChanged((Project) params[0], (Project) params[1], (String) params[2]);
|
undoHandler.stateChanged((Project) params[0], ((Project) params[1]).clone(), (String) params[2]);
|
||||||
break;
|
break;
|
||||||
case PROJECT_LOADED:
|
case PROJECT_LOADED:
|
||||||
if ((Boolean) params[1])
|
if ((Boolean) params[1])
|
||||||
|
|||||||
@@ -0,0 +1,314 @@
|
|||||||
|
package org.diylc.swing.plugins.explorer;
|
||||||
|
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.awt.Font;
|
||||||
|
import java.awt.GridBagConstraints;
|
||||||
|
import java.awt.GridBagLayout;
|
||||||
|
import java.awt.event.ItemEvent;
|
||||||
|
import java.awt.event.ItemListener;
|
||||||
|
import java.awt.event.MouseAdapter;
|
||||||
|
import java.awt.event.MouseEvent;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import javax.swing.AbstractListModel;
|
||||||
|
import javax.swing.JComboBox;
|
||||||
|
import javax.swing.JList;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.JScrollPane;
|
||||||
|
import javax.swing.JTextField;
|
||||||
|
import javax.swing.ListSelectionModel;
|
||||||
|
import javax.swing.SwingUtilities;
|
||||||
|
import javax.swing.event.ListSelectionEvent;
|
||||||
|
import javax.swing.event.ListSelectionListener;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
import org.diylc.common.IPlugInPort;
|
||||||
|
import org.diylc.core.IDIYComponent;
|
||||||
|
import org.diylc.lang.LangUtil;
|
||||||
|
import org.diylc.swing.gui.ComponentPopupMenu;
|
||||||
|
import org.diylc.swing.gui.SearchTextField;
|
||||||
|
|
||||||
|
public class ExplorerPane extends JPanel {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private static final Logger LOG = Logger.getLogger(ExplorerPane.class);
|
||||||
|
|
||||||
|
public static Font DEFAULT_FONT = new Font("Square721 BT", Font.PLAIN, 12);
|
||||||
|
|
||||||
|
private IPlugInPort plugInPort;
|
||||||
|
private JTextField searchField;
|
||||||
|
private JScrollPane componentScrollPane;
|
||||||
|
private ComponentListModel componentListModel;
|
||||||
|
private JList<IDIYComponent<?>> componentList;
|
||||||
|
private ComponentPopupMenu popupMenu;
|
||||||
|
private JComboBox<Sort> sortBox;
|
||||||
|
|
||||||
|
public ExplorerPane(IPlugInPort plugInPort) {
|
||||||
|
super();
|
||||||
|
this.plugInPort = plugInPort;
|
||||||
|
setName("Project Explorer");
|
||||||
|
|
||||||
|
setLayout(new GridBagLayout());
|
||||||
|
|
||||||
|
GridBagConstraints gbc = new GridBagConstraints();
|
||||||
|
gbc.gridx = 0;
|
||||||
|
gbc.gridy = 0;
|
||||||
|
gbc.fill = GridBagConstraints.HORIZONTAL;
|
||||||
|
gbc.weighty = 0;
|
||||||
|
gbc.gridwidth = 1;
|
||||||
|
|
||||||
|
add(getSearchField(), gbc);
|
||||||
|
|
||||||
|
gbc.gridy++;
|
||||||
|
|
||||||
|
gbc.fill = GridBagConstraints.HORIZONTAL;
|
||||||
|
gbc.weightx = 0;
|
||||||
|
gbc.weighty = 0;
|
||||||
|
|
||||||
|
add(getSortBox(), gbc);
|
||||||
|
|
||||||
|
gbc.gridy++;
|
||||||
|
|
||||||
|
gbc.fill = GridBagConstraints.BOTH;
|
||||||
|
gbc.weighty = 1;
|
||||||
|
gbc.weightx = 1;
|
||||||
|
|
||||||
|
add(getComponentScrollPane(), gbc);
|
||||||
|
|
||||||
|
setPreferredSize(new Dimension(180, 200));
|
||||||
|
}
|
||||||
|
|
||||||
|
public JTextField getSearchField() {
|
||||||
|
if (searchField == null) {
|
||||||
|
searchField = new SearchTextField(true, 'X', text -> {
|
||||||
|
getComponentListModel().setSearchText(text);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return searchField;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JComboBox<Sort> getSortBox() {
|
||||||
|
if (sortBox == null) {
|
||||||
|
sortBox = new JComboBox<Sort>(Sort.values());
|
||||||
|
sortBox.addItemListener(new ItemListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void itemStateChanged(ItemEvent e) {
|
||||||
|
getComponentListModel().setSort((Sort) e.getItem());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return sortBox;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JScrollPane getComponentScrollPane() {
|
||||||
|
if (componentScrollPane == null) {
|
||||||
|
componentScrollPane = new JScrollPane(getComponentList(),
|
||||||
|
JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
|
||||||
|
}
|
||||||
|
return componentScrollPane;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JList<IDIYComponent<?>> getComponentList() {
|
||||||
|
if (componentList == null) {
|
||||||
|
componentList = new JList<IDIYComponent<?>>();
|
||||||
|
componentList.setModel(getComponentListModel());
|
||||||
|
componentList.setFont(DEFAULT_FONT);
|
||||||
|
componentList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
|
||||||
|
componentList.addListSelectionListener(new ListSelectionListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void valueChanged(ListSelectionEvent e) {
|
||||||
|
if (e.getValueIsAdjusting())
|
||||||
|
return;
|
||||||
|
|
||||||
|
List<IDIYComponent<?>> selectedValuesList = componentList.getSelectedValuesList();
|
||||||
|
if (selectedValuesList.size() > 0 && !new HashSet<IDIYComponent<?>>(selectedValuesList)
|
||||||
|
.equals(new HashSet<IDIYComponent<?>>(plugInPort.getSelectedComponents()))) {
|
||||||
|
plugInPort.setSelection(selectedValuesList, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
componentList.addMouseListener(new MouseAdapter() {
|
||||||
|
|
||||||
|
private MouseEvent pressedEvent;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mousePressed(MouseEvent e) {
|
||||||
|
ExplorerPane.this.requestFocus();
|
||||||
|
pressedEvent = e;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseReleased(final MouseEvent e) {
|
||||||
|
// Invoke the rest of the code later so we get the chance to
|
||||||
|
// process selection messages.
|
||||||
|
SwingUtilities.invokeLater(new Runnable() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if (plugInPort.getNewComponentTypeSlot() == null && (e.isPopupTrigger()
|
||||||
|
|| (pressedEvent != null && pressedEvent.isPopupTrigger()))) {
|
||||||
|
|
||||||
|
final List<IDIYComponent<?>> selectedValues = componentList.getSelectedValuesList();
|
||||||
|
getComponentPopupMenu().prepareAndShowAt(selectedValues, selectedValues, e.getX(),
|
||||||
|
e.getY());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return componentList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ComponentListModel getComponentListModel() {
|
||||||
|
if (componentListModel == null) {
|
||||||
|
componentListModel = new ComponentListModel();
|
||||||
|
}
|
||||||
|
return componentListModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ComponentPopupMenu getComponentPopupMenu() {
|
||||||
|
if (popupMenu == null) {
|
||||||
|
popupMenu = new ComponentPopupMenu(plugInPort, getComponentList(), false);
|
||||||
|
}
|
||||||
|
return popupMenu;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setComponents(List<IDIYComponent<?>> components) {
|
||||||
|
this.getComponentListModel().setComponents(components);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSelection(Set<IDIYComponent<?>> selectedComponents) {
|
||||||
|
List<IDIYComponent<?>> selectedValuesList = componentList.getSelectedValuesList();
|
||||||
|
if (new HashSet<IDIYComponent<?>>(selectedValuesList)
|
||||||
|
.equals(new HashSet<IDIYComponent<?>>(plugInPort.getSelectedComponents())))
|
||||||
|
return;
|
||||||
|
|
||||||
|
final JList<IDIYComponent<?>> list = this.getComponentList();
|
||||||
|
|
||||||
|
if (selectedComponents.size() == 0) {
|
||||||
|
list.clearSelection();
|
||||||
|
} else {
|
||||||
|
|
||||||
|
int[] indices = new int[selectedComponents.size()];
|
||||||
|
int n = 0;
|
||||||
|
List<IDIYComponent<?>> components = this.getComponentListModel().getComponents();
|
||||||
|
for (int i = 0; i < components.size(); i++) {
|
||||||
|
indices[n] = -1; // this should not happen
|
||||||
|
if (selectedComponents.contains(components.get(i)))
|
||||||
|
indices[n++] = i;
|
||||||
|
if (n == indices.length)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
list.getSelectionModel().setValueIsAdjusting(true);
|
||||||
|
list.setSelectedIndices(indices);
|
||||||
|
list.getSelectionModel().setValueIsAdjusting(false);
|
||||||
|
int firstVisibleIndex = list.getFirstVisibleIndex();
|
||||||
|
int lastVisibleIndex = list.getFirstVisibleIndex();
|
||||||
|
// if none of the selected items is visible, jump to the first one
|
||||||
|
if (!Arrays.stream(indices)
|
||||||
|
.anyMatch(index -> firstVisibleIndex <= index && index <= lastVisibleIndex))
|
||||||
|
list.ensureIndexIsVisible(indices[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ComponentListModel extends AbstractListModel<IDIYComponent<?>> {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private List<IDIYComponent<?>> componentsRaw;
|
||||||
|
private List<IDIYComponent<?>> components;
|
||||||
|
|
||||||
|
private String searchText;
|
||||||
|
private Sort sort;
|
||||||
|
|
||||||
|
public void setComponents(List<IDIYComponent<?>> components) {
|
||||||
|
this.componentsRaw = components;
|
||||||
|
int oldSize = getSize();
|
||||||
|
|
||||||
|
refresh(oldSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<IDIYComponent<?>> getComponents() {
|
||||||
|
return components;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSort(Sort sort) {
|
||||||
|
this.sort = sort;
|
||||||
|
|
||||||
|
refresh(getSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSearchText(String searchText) {
|
||||||
|
this.searchText = searchText.toLowerCase();
|
||||||
|
|
||||||
|
refresh(getSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void refresh(int oldSize) {
|
||||||
|
if (sort == Sort.NAME) {
|
||||||
|
this.components =
|
||||||
|
componentsRaw.stream().sorted(Comparator.comparing(x -> x.toString().toLowerCase()))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
} else if (sort == Sort.TYPE) {
|
||||||
|
this.components = componentsRaw.stream()
|
||||||
|
.sorted(Comparator.comparing(x -> x.getClass().getName().toLowerCase())
|
||||||
|
.thenComparing(x -> x.toString().toLowerCase()))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
} else {
|
||||||
|
List<IDIYComponent<?>> componentsClone = new ArrayList<IDIYComponent<?>>(componentsRaw);
|
||||||
|
Collections.reverse(componentsClone);
|
||||||
|
this.components = componentsClone;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (searchText != null && !searchText.trim().isEmpty()) {
|
||||||
|
this.components = this.components.stream().filter(component -> {
|
||||||
|
return component.getName().toLowerCase().contains(searchText);
|
||||||
|
}).collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
int newSize = this.components.size();
|
||||||
|
|
||||||
|
fireContentsChanged(this, 0, Math.min(newSize, oldSize));
|
||||||
|
if (oldSize > newSize)
|
||||||
|
fireIntervalRemoved(this, newSize, oldSize);
|
||||||
|
else if (newSize > oldSize)
|
||||||
|
fireIntervalAdded(this, oldSize, newSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getSize() {
|
||||||
|
return this.components == null ? 0 : this.components.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IDIYComponent<?> getElementAt(int index) {
|
||||||
|
return this.components.get(index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static enum Sort {
|
||||||
|
Z_INDEX("Sort by Z-index"), NAME("Sort by Name"), TYPE("Sort by Type");
|
||||||
|
|
||||||
|
private String label;
|
||||||
|
|
||||||
|
Sort(String label) {
|
||||||
|
this.label = label;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return LangUtil.translate(label);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,110 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
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.plugins.explorer;
|
||||||
|
|
||||||
|
import java.awt.KeyEventDispatcher;
|
||||||
|
import java.awt.KeyboardFocusManager;
|
||||||
|
import java.awt.event.KeyEvent;
|
||||||
|
import java.util.EnumSet;
|
||||||
|
import java.util.Set;
|
||||||
|
import javax.swing.JComponent;
|
||||||
|
import javax.swing.SwingConstants;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
import org.diylc.appframework.miscutils.ConfigurationManager;
|
||||||
|
import org.diylc.common.BadPositionException;
|
||||||
|
import org.diylc.common.EventType;
|
||||||
|
import org.diylc.common.IPlugIn;
|
||||||
|
import org.diylc.common.IPlugInPort;
|
||||||
|
import org.diylc.core.IDIYComponent;
|
||||||
|
import org.diylc.core.Project;
|
||||||
|
import org.diylc.swing.ISwingUI;
|
||||||
|
import org.diylc.swing.plugins.config.ConfigPlugin;
|
||||||
|
|
||||||
|
public class ExplorerPlugin implements IPlugIn {
|
||||||
|
|
||||||
|
private static final Logger LOG = Logger.getLogger(ExplorerPlugin.class);
|
||||||
|
|
||||||
|
private IPlugInPort plugInPort;
|
||||||
|
private ISwingUI swingUI;
|
||||||
|
private ExplorerPane explorerPane;
|
||||||
|
private JComponent canvasPanel;
|
||||||
|
|
||||||
|
public ExplorerPlugin(ISwingUI swingUI, JComponent canvasPanel) {
|
||||||
|
super();
|
||||||
|
this.swingUI = swingUI;
|
||||||
|
this.canvasPanel = canvasPanel;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EnumSet<EventType> getSubscribedEventTypes() {
|
||||||
|
return EnumSet.of(EventType.FILE_STATUS_CHANGED, EventType.PROJECT_LOADED, EventType.PROJECT_MODIFIED, EventType.SELECTION_CHANGED);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Override
|
||||||
|
public void processMessage(EventType eventType, Object... params) {
|
||||||
|
switch (eventType) {
|
||||||
|
case PROJECT_MODIFIED:
|
||||||
|
getExplorerPane().setComponents(((Project)params[1]).getComponents());
|
||||||
|
break;
|
||||||
|
case PROJECT_LOADED:
|
||||||
|
getExplorerPane().setComponents(((Project)params[0]).getComponents());
|
||||||
|
break;
|
||||||
|
case SELECTION_CHANGED:
|
||||||
|
getExplorerPane().setSelection((Set<IDIYComponent<?>>)params[0]);
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void connect(IPlugInPort plugInPort) {
|
||||||
|
this.plugInPort = plugInPort;
|
||||||
|
try {
|
||||||
|
this.swingUI.injectGUIComponent(getExplorerPane(), SwingConstants.RIGHT, true, ConfigPlugin.PROJECT_EXPLORER);
|
||||||
|
} catch (BadPositionException e) {
|
||||||
|
LOG.error("Could not install project explorer", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(new KeyEventDispatcher() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean dispatchKeyEvent(KeyEvent e) {
|
||||||
|
if ((canvasPanel.hasFocus() || explorerPane.hasFocus())
|
||||||
|
&& e.getKeyChar() == 'x'
|
||||||
|
&& ConfigurationManager.getInstance()
|
||||||
|
.readBoolean(ConfigPlugin.PROJECT_EXPLORER, true)) {
|
||||||
|
explorerPane.getSearchField().requestFocusInWindow();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public ExplorerPane getExplorerPane() {
|
||||||
|
if (explorerPane == null) {
|
||||||
|
explorerPane = new ExplorerPane(plugInPort);
|
||||||
|
}
|
||||||
|
return explorerPane;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -106,7 +106,7 @@ public class StatusBar extends JPanel implements IPlugIn {
|
|||||||
private static final Format sizeFormat = new DecimalFormat("0.##");
|
private static final Format sizeFormat = new DecimalFormat("0.##");
|
||||||
private static final int MAX_SELECTED_COMPONENTS = 15;
|
private static final int MAX_SELECTED_COMPONENTS = 15;
|
||||||
|
|
||||||
private JComboBox zoomBox;
|
private JComboBox<Double> zoomBox;
|
||||||
private UpdateLabel updateLabel;
|
private UpdateLabel updateLabel;
|
||||||
private JLabel announcementLabel;
|
private JLabel announcementLabel;
|
||||||
private JLabel recentChangesLabel;
|
private JLabel recentChangesLabel;
|
||||||
@@ -142,7 +142,7 @@ public class StatusBar extends JPanel implements IPlugIn {
|
|||||||
setLayout(new GridBagLayout());
|
setLayout(new GridBagLayout());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
swingUI.injectGUIComponent(this, SwingUtilities.BOTTOM, false);
|
swingUI.injectGUIComponent(this, SwingUtilities.BOTTOM, false, null);
|
||||||
} catch (BadPositionException e) {
|
} catch (BadPositionException e) {
|
||||||
LOG.error("Could not install status bar", e);
|
LOG.error("Could not install status bar", e);
|
||||||
}
|
}
|
||||||
@@ -202,9 +202,9 @@ public class StatusBar extends JPanel implements IPlugIn {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private JComboBox getZoomBox() {
|
private JComboBox<Double> getZoomBox() {
|
||||||
if (zoomBox == null) {
|
if (zoomBox == null) {
|
||||||
zoomBox = new JComboBox(plugInPort.getAvailableZoomLevels());
|
zoomBox = new JComboBox<Double>(plugInPort.getAvailableZoomLevels());
|
||||||
zoomBox.setSelectedItem(plugInPort.getZoomLevel());
|
zoomBox.setSelectedItem(plugInPort.getZoomLevel());
|
||||||
zoomBox.setFocusable(false);
|
zoomBox.setFocusable(false);
|
||||||
zoomBox.setRenderer(new PercentageListCellRenderer());
|
zoomBox.setRenderer(new PercentageListCellRenderer());
|
||||||
|
|||||||
@@ -106,9 +106,8 @@ public class ComponentButtonFactory {
|
|||||||
if (Utils.isMac() ? e.isControlDown() : e.isMetaDown()) {
|
if (Utils.isMac() ? e.isControlDown() : e.isMetaDown()) {
|
||||||
newSelection.addAll(plugInPort.getSelectedComponents());
|
newSelection.addAll(plugInPort.getSelectedComponents());
|
||||||
}
|
}
|
||||||
plugInPort.updateSelection(newSelection);
|
plugInPort.setSelection(newSelection, true);
|
||||||
plugInPort.setNewComponentTypeSlot(null, null, null, false);
|
plugInPort.setNewComponentTypeSlot(null, null, null, false);
|
||||||
plugInPort.refresh();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -32,12 +32,11 @@ import org.diylc.common.IPlugIn;
|
|||||||
import org.diylc.common.IPlugInPort;
|
import org.diylc.common.IPlugInPort;
|
||||||
import org.diylc.swing.ISwingUI;
|
import org.diylc.swing.ISwingUI;
|
||||||
import org.diylc.swing.plugins.config.ConfigPlugin;
|
import org.diylc.swing.plugins.config.ConfigPlugin;
|
||||||
import org.diylc.swing.plugins.statusbar.StatusBar;
|
|
||||||
|
|
||||||
|
|
||||||
public class ToolBox implements IPlugIn {
|
public class ToolBox implements IPlugIn {
|
||||||
|
|
||||||
private static final Logger LOG = Logger.getLogger(StatusBar.class);
|
private static final Logger LOG = Logger.getLogger(ToolBox.class);
|
||||||
|
|
||||||
private ISwingUI swingUI;
|
private ISwingUI swingUI;
|
||||||
private IPlugInPort plugInPort;
|
private IPlugInPort plugInPort;
|
||||||
@@ -52,7 +51,7 @@ public class ToolBox implements IPlugIn {
|
|||||||
public void connect(IPlugInPort plugInPort) {
|
public void connect(IPlugInPort plugInPort) {
|
||||||
this.plugInPort = plugInPort;
|
this.plugInPort = plugInPort;
|
||||||
try {
|
try {
|
||||||
swingUI.injectGUIComponent(getComponentTabbedPane(), SwingConstants.TOP, false);
|
swingUI.injectGUIComponent(getComponentTabbedPane(), SwingConstants.TOP, false, null);
|
||||||
} catch (BadPositionException e) {
|
} catch (BadPositionException e) {
|
||||||
LOG.error("Could not install the toolbox", e);
|
LOG.error("Could not install the toolbox", e);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ public class ComponentTree implements IPlugIn {
|
|||||||
public void connect(IPlugInPort plugInPort) {
|
public void connect(IPlugInPort plugInPort) {
|
||||||
this.plugInPort = plugInPort;
|
this.plugInPort = plugInPort;
|
||||||
try {
|
try {
|
||||||
swingUI.injectGUIComponent(getTreePanel(), SwingConstants.LEFT, true);
|
swingUI.injectGUIComponent(getTreePanel(), SwingConstants.LEFT, true, null);
|
||||||
} catch (BadPositionException e) {
|
} catch (BadPositionException e) {
|
||||||
LOG.error("Could not install the component tree", e);
|
LOG.error("Could not install the component tree", e);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,12 +17,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.diylc.swing.plugins.tree;
|
package org.diylc.swing.plugins.tree;
|
||||||
|
|
||||||
import java.awt.AlphaComposite;
|
|
||||||
import java.awt.Color;
|
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
import java.awt.Graphics;
|
|
||||||
import java.awt.Graphics2D;
|
|
||||||
import java.awt.GridBagConstraints;
|
import java.awt.GridBagConstraints;
|
||||||
import java.awt.GridBagLayout;
|
import java.awt.GridBagLayout;
|
||||||
import java.awt.dnd.DnDConstants;
|
import java.awt.dnd.DnDConstants;
|
||||||
@@ -30,8 +26,6 @@ import java.awt.dnd.DragSource;
|
|||||||
import java.awt.dnd.DropTarget;
|
import java.awt.dnd.DropTarget;
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.awt.event.ActionListener;
|
import java.awt.event.ActionListener;
|
||||||
import java.awt.event.FocusAdapter;
|
|
||||||
import java.awt.event.FocusEvent;
|
|
||||||
import java.awt.event.MouseAdapter;
|
import java.awt.event.MouseAdapter;
|
||||||
import java.awt.event.MouseEvent;
|
import java.awt.event.MouseEvent;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -41,7 +35,6 @@ import java.util.Iterator;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import javax.swing.AbstractAction;
|
import javax.swing.AbstractAction;
|
||||||
import javax.swing.Icon;
|
|
||||||
import javax.swing.JMenu;
|
import javax.swing.JMenu;
|
||||||
import javax.swing.JMenuItem;
|
import javax.swing.JMenuItem;
|
||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
@@ -52,8 +45,6 @@ import javax.swing.JTextField;
|
|||||||
import javax.swing.JTree;
|
import javax.swing.JTree;
|
||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
import javax.swing.ToolTipManager;
|
import javax.swing.ToolTipManager;
|
||||||
import javax.swing.event.DocumentEvent;
|
|
||||||
import javax.swing.event.DocumentListener;
|
|
||||||
import javax.swing.event.PopupMenuEvent;
|
import javax.swing.event.PopupMenuEvent;
|
||||||
import javax.swing.event.PopupMenuListener;
|
import javax.swing.event.PopupMenuListener;
|
||||||
import javax.swing.event.TreeModelEvent;
|
import javax.swing.event.TreeModelEvent;
|
||||||
@@ -75,6 +66,7 @@ import org.diylc.core.IView;
|
|||||||
import org.diylc.core.Template;
|
import org.diylc.core.Template;
|
||||||
import org.diylc.lang.LangUtil;
|
import org.diylc.lang.LangUtil;
|
||||||
import org.diylc.swing.ISwingUI;
|
import org.diylc.swing.ISwingUI;
|
||||||
|
import org.diylc.swing.gui.SearchTextField;
|
||||||
import org.diylc.swing.images.IconLoader;
|
import org.diylc.swing.images.IconLoader;
|
||||||
import org.diylc.swing.plugins.toolbox.ComponentButtonFactory;
|
import org.diylc.swing.plugins.toolbox.ComponentButtonFactory;
|
||||||
|
|
||||||
@@ -104,6 +96,8 @@ public class TreePanel extends JPanel {
|
|||||||
public TreePanel(IPlugInPort plugInPort, ISwingUI swingUI) {
|
public TreePanel(IPlugInPort plugInPort, ISwingUI swingUI) {
|
||||||
this.plugInPort = plugInPort;
|
this.plugInPort = plugInPort;
|
||||||
this.swingUI = swingUI;
|
this.swingUI = swingUI;
|
||||||
|
|
||||||
|
setName("Toolbox");
|
||||||
setLayout(new GridBagLayout());
|
setLayout(new GridBagLayout());
|
||||||
|
|
||||||
GridBagConstraints gbc = new GridBagConstraints();
|
GridBagConstraints gbc = new GridBagConstraints();
|
||||||
@@ -397,58 +391,9 @@ public class TreePanel extends JPanel {
|
|||||||
|
|
||||||
public JTextField getSearchField() {
|
public JTextField getSearchField() {
|
||||||
if (searchField == null) {
|
if (searchField == null) {
|
||||||
searchField = new JTextField() {
|
searchField = new SearchTextField(true, 'Q', text -> {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void paint(Graphics g) {
|
|
||||||
super.paint(g);
|
|
||||||
|
|
||||||
Graphics2D g2d = (Graphics2D) g;
|
|
||||||
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f));
|
|
||||||
Icon icon = IconLoader.SearchBox.getIcon();
|
|
||||||
icon.paintIcon(searchField, g2d, searchField.getWidth() - 18, 3);
|
|
||||||
|
|
||||||
if (searchField.getText().trim().length() == 0 && !searchField.hasFocus()) {
|
|
||||||
g2d.setColor(Color.gray);
|
|
||||||
g2d.setFont(searchField.getFont());
|
|
||||||
g2d.drawString("Search (press Q to jump here)", 4, 3 + searchField.getFont().getSize());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
searchField.addFocusListener(new FocusAdapter() {
|
|
||||||
@Override
|
|
||||||
public void focusGained(FocusEvent e) {
|
|
||||||
searchField.repaint();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void focusLost(FocusEvent e) {
|
|
||||||
searchField.repaint();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
searchField.getDocument().addDocumentListener(new DocumentListener() {
|
|
||||||
|
|
||||||
public void changedUpdate(DocumentEvent e) {
|
|
||||||
process();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void removeUpdate(DocumentEvent e) {
|
|
||||||
process();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void insertUpdate(DocumentEvent e) {
|
|
||||||
process();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void process() {
|
|
||||||
String text = searchField.getText();
|
|
||||||
CustomTreeModel model = getTreeModel();
|
CustomTreeModel model = getTreeModel();
|
||||||
model.setSearchText(text);
|
model.setSearchText(text);
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return searchField;
|
return searchField;
|
||||||
@@ -555,8 +500,7 @@ public class TreePanel extends JPanel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
plugInPort.updateSelection(newSelection);
|
plugInPort.setSelection(newSelection, true);
|
||||||
plugInPort.refresh();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user