diff --git a/diylc/diylc-core/src/org/diylc/common/ISelectionProcessor.java b/diylc/diylc-core/src/org/diylc/common/ISelectionProcessor.java index b0a8bce8..44d11c87 100644 --- a/diylc/diylc-core/src/org/diylc/common/ISelectionProcessor.java +++ b/diylc/diylc-core/src/org/diylc/common/ISelectionProcessor.java @@ -50,9 +50,10 @@ public interface ISelectionProcessor { * Updates the selection with the specified list of component. Also, updates control point map * with all components that are stuck to the newly selected components. * - * @param newSelection + * @param newSelection + * @param panToSelection */ - void updateSelection(Collection> newSelection); + void setSelection(Collection> newSelection, boolean panToSelection); /** * Finds all components at the specified location, sorted by z-index from top to bottom. Location diff --git a/diylc/diylc-core/src/org/diylc/components/AbstractComponent.java b/diylc/diylc-core/src/org/diylc/components/AbstractComponent.java index 7ccc7450..ff51f4ab 100644 --- a/diylc/diylc-core/src/org/diylc/components/AbstractComponent.java +++ b/diylc/diylc-core/src/org/diylc/components/AbstractComponent.java @@ -83,7 +83,7 @@ public abstract class AbstractComponent implements IDIYComponent { @Override public String toString() { - return name; + return name == null ? "(null)" : name; } @Override @@ -201,7 +201,7 @@ public abstract class AbstractComponent implements IDIYComponent { } catch (Exception e) { throw new CloneNotSupportedException("Could not clone the component. Reason: " + e.getMessage()); } - } + } @Override public boolean equalsTo(IDIYComponent other) { diff --git a/diylc/diylc-core/src/org/diylc/presenter/Presenter.java b/diylc/diylc-core/src/org/diylc/presenter/Presenter.java index d0e2bc34..350f824d 100644 --- a/diylc/diylc-core/src/org/diylc/presenter/Presenter.java +++ b/diylc/diylc-core/src/org/diylc/presenter/Presenter.java @@ -674,7 +674,7 @@ public class Presenter implements IPlugInPort { } // Notify the listeners. if (!oldProject.equals(currentProject)) { - messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject.clone(), "Add " + messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject, "Add " + componentTypeSlot.getName()); drawingManager.clearContinuityArea(); projectFileManager.notifyFileChange(); @@ -798,7 +798,7 @@ public class Presenter implements IPlugInPort { mirrorComponents(this.selectedComponents, IComponentTransformer.VERTICAL, snapToGrid); } else return false; - messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject.clone(), + messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject, "Rotate Selection"); messageDispatcher.dispatchMessage(EventType.REPAINT); drawingManager.clearContinuityArea(); @@ -842,7 +842,7 @@ public class Presenter implements IPlugInPort { Project oldProject = currentProject.clone(); 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); return true; } @@ -1060,7 +1060,7 @@ public class Presenter implements IPlugInPort { Project oldProject = currentProject.clone(); 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); drawingManager.clearContinuityArea(); } @@ -1427,7 +1427,7 @@ public class Presenter implements IPlugInPort { LOG.trace("Rotating selected components"); Project oldProject = currentProject.clone(); rotateComponents(this.selectedComponents, direction, isSnapToGrid()); - messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject.clone(), + messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject, "Rotate Selection"); drawingManager.clearContinuityArea(); messageDispatcher.dispatchMessage(EventType.REPAINT); @@ -1540,7 +1540,7 @@ public class Presenter implements IPlugInPort { mirrorComponents(selectedComponents, direction, isSnapToGrid()); - messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject.clone(), + messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject, MIRROR_SELECTION); messageDispatcher.dispatchMessage(EventType.REPAINT); drawingManager.clearContinuityArea(); @@ -1675,7 +1675,7 @@ public class Presenter implements IPlugInPort { // operation. if (!preDragProject.equals(currentProject)) { - messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, preDragProject, currentProject.clone(), "Drag"); + messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, preDragProject, currentProject, "Drag"); drawingManager.clearContinuityArea(); projectFileManager.notifyFileChange(); } @@ -1725,7 +1725,7 @@ public class Presenter implements IPlugInPort { updateSelection(newSelection); - messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject.clone(), "Duplicate"); + messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject, "Duplicate"); drawingManager.clearContinuityArea(); projectFileManager.notifyFileChange(); messageDispatcher.dispatchMessage(EventType.REPAINT); @@ -1749,7 +1749,7 @@ public class Presenter implements IPlugInPort { currentProject.getComponents().removeAll(selectedComponents); DrawingCache.Instance.invalidate(selectedComponents); - messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject.clone(), "Delete"); + messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject, "Delete"); drawingManager.clearContinuityArea(); projectFileManager.notifyFileChange(); updateSelection(EMPTY_SELECTION); @@ -1784,7 +1784,7 @@ public class Presenter implements IPlugInPort { // Notify the listeners. messageDispatcher.dispatchMessage(EventType.REPAINT); if (!oldProject.equals(currentProject)) { - messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject.clone(), "Group"); + messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject, "Group"); projectFileManager.notifyFileChange(); } } @@ -1797,7 +1797,7 @@ public class Presenter implements IPlugInPort { // Notify the listeners. messageDispatcher.dispatchMessage(EventType.REPAINT); if (!oldProject.equals(currentProject)) { - messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject.clone(), "Ungroup"); + messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject, "Ungroup"); projectFileManager.notifyFileChange(); } } @@ -1815,7 +1815,7 @@ public class Presenter implements IPlugInPort { messageDispatcher.dispatchMessage(EventType.REPAINT); messageDispatcher.dispatchMessage(EventType.LAYER_STATE_CHANGED, currentProject.getLockedLayers()); if (!oldProject.equals(currentProject)) { - messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject.clone(), + messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject, locked ? "Lock Layer" : "Unlock Layer"); projectFileManager.notifyFileChange(); } @@ -1834,7 +1834,7 @@ public class Presenter implements IPlugInPort { messageDispatcher.dispatchMessage(EventType.REPAINT); messageDispatcher.dispatchMessage(EventType.LAYER_VISIBILITY_CHANGED, currentProject.getHiddenLayers()); if (!oldProject.equals(currentProject)) { - messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject.clone(), + messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject, visible ? "Show Layer" : "Hide Layer"); projectFileManager.notifyFileChange(); } @@ -1887,7 +1887,7 @@ public class Presenter implements IPlugInPort { } } 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(); messageDispatcher.dispatchMessage(EventType.REPAINT); } @@ -1940,7 +1940,7 @@ public class Presenter implements IPlugInPort { } } if (!oldProject.equals(currentProject)) { - messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject.clone(), + messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject, "Bring to Front"); projectFileManager.notifyFileChange(); messageDispatcher.dispatchMessage(EventType.REPAINT); @@ -2033,13 +2033,18 @@ public class Presenter implements IPlugInPort { .getComponents())); } - messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject.clone(), + messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject, "Renumber selection"); projectFileManager.notifyFileChange(); messageDispatcher.dispatchMessage(EventType.REPAINT); } - public void updateSelection(Collection> newSelection) { + public void setSelection(Collection> newSelection, boolean panToSelection) { + this.updateSelection(newSelection); + messageDispatcher.dispatchMessage(EventType.REPAINT, panToSelection); + } + + private void updateSelection(Collection> newSelection) { this.selectedComponents = new HashSet>(newSelection); Map, Set> controlPointMap = new HashMap, Set>(); for (IDIYComponent component : selectedComponents) { @@ -2342,7 +2347,7 @@ public class Presenter implements IPlugInPort { } finally { // Notify the listeners. if (!oldProject.equals(currentProject)) { - messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject.clone(), + messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject, "Edit Selection"); drawingManager.clearContinuityArea(); projectFileManager.notifyFileChange(); @@ -2380,7 +2385,7 @@ public class Presenter implements IPlugInPort { } finally { // Notify the listeners. if (!oldProject.equals(currentProject)) { - messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject.clone(), + messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject, "Edit Project"); drawingManager.clearContinuityArea(); projectFileManager.notifyFileChange(); @@ -2403,7 +2408,7 @@ public class Presenter implements IPlugInPort { } finally { // Notify the listeners. if (!oldProject.equals(currentProject)) { - messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject.clone(), + messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject, editor.getEditAction()); drawingManager.clearContinuityArea(); projectFileManager.notifyFileChange(); @@ -2426,7 +2431,7 @@ public class Presenter implements IPlugInPort { // Notify the listeners. if (!oldProject.equals(currentProject)) { messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, - currentProject.clone(), "Edit Project"); + currentProject, "Edit Project"); drawingManager.clearContinuityArea(); projectFileManager.notifyFileChange(); } @@ -2652,7 +2657,7 @@ public class Presenter implements IPlugInPort { // Notify the listeners. if (!oldProject.equals(currentProject)) { - messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject.clone(), + messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject, "Edit Selection"); drawingManager.clearContinuityArea(); projectFileManager.notifyFileChange(); @@ -2718,7 +2723,7 @@ public class Presenter implements IPlugInPort { } finally { // Notify the listeners. if (!oldProject.equals(currentProject)) { - messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject.clone(), + messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject, locked ? "Lock Component" : "Unlock Component"); projectFileManager.notifyFileChange(); } diff --git a/diylc/diylc-core/src/org/diylc/presenter/update.xml b/diylc/diylc-core/src/org/diylc/presenter/update.xml index 2d6f1df9..f8dd09d4 100644 --- a/diylc/diylc-core/src/org/diylc/presenter/update.xml +++ b/diylc/diylc-core/src/org/diylc/presenter/update.xml @@ -4188,7 +4188,11 @@ NEW_FEATURE - Keyboard shortcuts for toggling layer visibility using Ctrl + 1 through Ctrl + 5 + Added Project Explorer pane in the right-hand side for quick access to components + + + NEW_FEATURE + Keyboard shortcuts for toggling layer visibility using Ctrl + 1 through Ctrl + 6 IMPROVEMENT diff --git a/diylc/diylc-library/lib/diylc-core.jar b/diylc/diylc-library/lib/diylc-core.jar index 95defb85..06f6a37d 100644 Binary files a/diylc/diylc-library/lib/diylc-core.jar and b/diylc/diylc-library/lib/diylc-core.jar differ diff --git a/diylc/diylc-swing/dict.txt b/diylc/diylc-swing/dict.txt index 5f715562..dbe01e1e 100644 --- a/diylc/diylc-swing/dict.txt +++ b/diylc/diylc-swing/dict.txt @@ -133,9 +133,13 @@ SPDT (On/Off/On) SPDT (On/On) SPST Shorting +Show Project Explorer Single - North Single - South Six +Sort by Name +Sort by Type +Sort by Z-index Source Style Source Type Srpski diff --git a/diylc/diylc-swing/lib/diylc-core.jar b/diylc/diylc-swing/lib/diylc-core.jar index 95defb85..06f6a37d 100644 Binary files a/diylc/diylc-swing/lib/diylc-core.jar and b/diylc/diylc-swing/lib/diylc-core.jar differ diff --git a/diylc/diylc-swing/library/main.jar b/diylc/diylc-swing/library/main.jar index f418e25b..f20195bb 100644 Binary files a/diylc/diylc-swing/library/main.jar and b/diylc/diylc-swing/library/main.jar differ diff --git a/diylc/diylc-swing/src/org/diylc/swing/ActionFactory.java b/diylc/diylc-swing/src/org/diylc/swing/ActionFactory.java index 50b04529..ea46b3ec 100644 --- a/diylc/diylc-swing/src/org/diylc/swing/ActionFactory.java +++ b/diylc/diylc-swing/src/org/diylc/swing/ActionFactory.java @@ -1821,7 +1821,7 @@ public class ActionFactory { @Override public void valueChanged(String key, Object value) { - putValue(AbstractAction.SELECTED_KEY, (Boolean) value); + putValue(AbstractAction.SELECTED_KEY, Boolean.TRUE.equals(value)); } }); } diff --git a/diylc/diylc-swing/src/org/diylc/swing/ISwingUI.java b/diylc/diylc-swing/src/org/diylc/swing/ISwingUI.java index cb749374..32e629d2 100644 --- a/diylc/diylc-swing/src/org/diylc/swing/ISwingUI.java +++ b/diylc/diylc-swing/src/org/diylc/swing/ISwingUI.java @@ -53,10 +53,11 @@ public interface ISwingUI extends IView { * * @param component * @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 */ - 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 action is set to diff --git a/diylc/diylc-swing/src/org/diylc/swing/gui/CollapsiblePanel.java b/diylc/diylc-swing/src/org/diylc/swing/gui/CollapsiblePanel.java index 2e10804c..df2cb25a 100644 --- a/diylc/diylc-swing/src/org/diylc/swing/gui/CollapsiblePanel.java +++ b/diylc/diylc-swing/src/org/diylc/swing/gui/CollapsiblePanel.java @@ -1,24 +1,21 @@ /* - - 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 . - -*/ + * + * 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 + * . + * + */ package org.diylc.swing.gui; import java.awt.BorderLayout; @@ -30,23 +27,28 @@ import java.awt.event.ComponentListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; +import java.util.Arrays; +import java.util.Optional; import javax.swing.JPanel; import javax.swing.SwingConstants; 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. * * @author bancika */ public class CollapsiblePanel extends JPanel { - + private static final long serialVersionUID = 1L; - + private static int BORDER_THICKNESS = 4; - + private MatteBorderEx border; - + private String visibilityConfigKey; + private Color defaultColor = Color.lightGray; private Color highlightColor = Color.decode("#66CCFF"); @@ -54,32 +56,42 @@ public class CollapsiblePanel extends JPanel { * * @param position designates the direction in which the panel should collapse */ - public CollapsiblePanel(int position) { - border = new MatteBorderEx(position == SwingConstants.BOTTOM ? BORDER_THICKNESS : 0, - position == SwingConstants.RIGHT ? BORDER_THICKNESS : 0, - position == SwingConstants.TOP ? BORDER_THICKNESS : 0, - position == SwingConstants.LEFT ? BORDER_THICKNESS : 0, defaultColor); - setToolTipText("Click to collapse"); - setBorder(border); - BorderLayout borderLayout = new BorderLayout(); - setLayout(borderLayout); - addMouseListener(mouseListener); + public CollapsiblePanel(int position, String visibilityConfigKey) { + this.visibilityConfigKey = visibilityConfigKey; + border = new MatteBorderEx(position == SwingConstants.BOTTOM ? BORDER_THICKNESS : 0, + position == SwingConstants.RIGHT ? BORDER_THICKNESS : 0, + position == SwingConstants.TOP ? BORDER_THICKNESS : 0, + position == SwingConstants.LEFT ? BORDER_THICKNESS : 0, defaultColor); + setToolTipText("Click to collapse"); + setBorder(border); + BorderLayout borderLayout = new BorderLayout(); + setLayout(borderLayout); + 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() { - @Override - public void mouseClicked(MouseEvent e) { - toggleVisibility(); - } - - public void mouseEntered(MouseEvent e) { - border.setMatteColor(highlightColor); - }; - - public void mouseExited(MouseEvent e) { - border.setMatteColor(defaultColor); - }; - }; + @Override + public void mouseClicked(MouseEvent e) { + toggleVisibility(); + } + + public void mouseEntered(MouseEvent e) { + border.setMatteColor(highlightColor); + }; + + public void mouseExited(MouseEvent e) { + border.setMatteColor(defaultColor); + }; + }; public Color getDefaultColor() { return defaultColor; @@ -98,110 +110,130 @@ public class CollapsiblePanel extends JPanel { } ComponentListener contentComponentListener = new ComponentAdapter() { - @Override - public void componentShown(ComponentEvent e) { - updateBorderTitle(); - } - @Override - public void componentHidden(ComponentEvent e) { - updateBorderTitle(); - } + @Override + public void componentShown(ComponentEvent e) { + updateBorderTitle(); + } + + @Override + public void componentHidden(ComponentEvent e) { + updateBorderTitle(); + } }; @Override public Component add(Component comp) { - comp.addComponentListener(contentComponentListener); - Component r = super.add(comp); - updateBorderTitle(); - return r; + comp.addComponentListener(contentComponentListener); + Component r = super.add(comp); + updateBorderTitle(); + if (!ConfigurationManager.getInstance().readBoolean(visibilityConfigKey, true)) { + comp.setVisible(false); + } + return r; } @Override public Component add(String name, Component comp) { - comp.addComponentListener(contentComponentListener); - Component r = super.add(name, comp); - updateBorderTitle(); - return r; + comp.addComponentListener(contentComponentListener); + Component r = super.add(name, comp); + updateBorderTitle(); + if (!ConfigurationManager.getInstance().readBoolean(visibilityConfigKey, true)) { + comp.setVisible(false); + } + return r; } @Override public Component add(Component comp, int index) { - comp.addComponentListener(contentComponentListener); - Component r = super.add(comp, index); - updateBorderTitle(); - return r; + comp.addComponentListener(contentComponentListener); + Component r = super.add(comp, index); + updateBorderTitle(); + return r; } @Override public void add(Component comp, Object constraints) { - comp.addComponentListener(contentComponentListener); - super.add(comp, constraints); - updateBorderTitle(); + comp.addComponentListener(contentComponentListener); + super.add(comp, constraints); + updateBorderTitle(); + if (!ConfigurationManager.getInstance().readBoolean(visibilityConfigKey, true)) { + comp.setVisible(false); + } } @Override public void add(Component comp, Object constraints, int index) { - comp.addComponentListener(contentComponentListener); - super.add(comp, constraints, index); - updateBorderTitle(); + comp.addComponentListener(contentComponentListener); + super.add(comp, constraints, index); + updateBorderTitle(); + if (!ConfigurationManager.getInstance().readBoolean(visibilityConfigKey, true)) { + comp.setVisible(false); + } } @Override public void remove(int index) { - Component comp = getComponent(index); - comp.removeComponentListener(contentComponentListener); - super.remove(index); + Component comp = getComponent(index); + comp.removeComponentListener(contentComponentListener); + super.remove(index); } @Override public void remove(Component comp) { - comp.removeComponentListener(contentComponentListener); - super.remove(comp); + comp.removeComponentListener(contentComponentListener); + super.remove(comp); } @Override public void removeAll() { - for (Component c : getComponents()) { - c.removeComponentListener(contentComponentListener); - } - super.removeAll(); + for (Component c : getComponents()) { + c.removeComponentListener(contentComponentListener); + } + super.removeAll(); } protected void toggleVisibility() { - toggleVisibility(hasInvisibleComponent()); + boolean invisible = hasInvisibleComponent(); + ConfigurationManager.getInstance().writeValue(visibilityConfigKey, invisible); + toggleVisibility(invisible); } protected void toggleVisibility(boolean visible) { - for (Component c : getComponents()) { - c.setVisible(visible); - } - updateBorderTitle(); + for (Component c : getComponents()) { + c.setVisible(visible); + } + updateBorderTitle(); } protected void updateBorderTitle() { - + boolean invisible = hasInvisibleComponent(); + Optional 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() { - for (Component c : getComponents()) { - if (!c.isVisible()) { - return true; - } + for (Component c : getComponents()) { + if (!c.isVisible()) { + return true; } - return false; + } + return false; } class MatteBorderEx extends MatteBorder { - + public MatteBorderEx(int top, int left, int bottom, int right, Color matteColor) { super(top, left, bottom, right, matteColor); } private static final long serialVersionUID = 1L; - + public void setMatteColor(Color color) { this.color = color; repaint(); } } -} \ No newline at end of file +} diff --git a/diylc/diylc-swing/src/org/diylc/swing/gui/ComponentPopupMenu.java b/diylc/diylc-swing/src/org/diylc/swing/gui/ComponentPopupMenu.java new file mode 100644 index 00000000..46b372eb --- /dev/null +++ b/diylc/diylc-swing/src/org/diylc/swing/gui/ComponentPopupMenu.java @@ -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 . + +*/ +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> componentsForSelection, Collection> 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> 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> newSelection = new ArrayList>(); + newSelection.add(finalComponent); + plugInPort.setSelection(newSelection, false); + } + }); + getSelectionMenu().add(item); + } + } + + private void updateApplyTemplateMenu() { + JMenu applyMenu = getApplyTemplateMenu(); + applyMenu.removeAll(); + List