mirror of
https://github.com/bancika/diy-layout-creator
synced 2026-11-10 17:22:09 +10:00
Added "Find" functionality that locates and selects component(s)
matching the search text
This commit is contained in:
@@ -102,5 +102,9 @@ public enum EventType {
|
|||||||
/**
|
/**
|
||||||
* Called to update the status message. New status message is passed as a first parameter.
|
* Called to update the status message. New status message is passed as a first parameter.
|
||||||
*/
|
*/
|
||||||
STATUS_MESSAGE_CHANGED;
|
STATUS_MESSAGE_CHANGED,
|
||||||
|
/**
|
||||||
|
* Signals the listeners to scroll to selection.
|
||||||
|
*/
|
||||||
|
SCROLL_TO;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -113,5 +113,12 @@ public interface ISelectionProcessor {
|
|||||||
* @param yOffset
|
* @param yOffset
|
||||||
* @param includeStuckComponents
|
* @param includeStuckComponents
|
||||||
*/
|
*/
|
||||||
void nudgeSelection(Size xOffset, Size yOffset, boolean includeStuckComponents);
|
void nudgeSelection(Size xOffset, Size yOffset, boolean includeStuckComponents);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Selects components that match the criteria.
|
||||||
|
*
|
||||||
|
* @param criteria
|
||||||
|
*/
|
||||||
|
void selectMatching(String criteria);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,5 +32,25 @@ public enum Orientation {
|
|||||||
} else {
|
} else {
|
||||||
return name().replace("_", "") + " degrees clockwise";
|
return name().replace("_", "") + " degrees clockwise";
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public double toDegrees() {
|
||||||
|
switch (this) {
|
||||||
|
case DEFAULT:
|
||||||
|
return 0;
|
||||||
|
case _180:
|
||||||
|
return 180;
|
||||||
|
case _270:
|
||||||
|
return 270;
|
||||||
|
case _90:
|
||||||
|
return 90;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double toRadians() {
|
||||||
|
return Math.toRadians(toDegrees());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1003,6 +1003,19 @@ public class Presenter implements IPlugInPort {
|
|||||||
messageDispatcher.dispatchMessage(EventType.REPAINT);
|
messageDispatcher.dispatchMessage(EventType.REPAINT);
|
||||||
drawingManager.clearContinuityArea();
|
drawingManager.clearContinuityArea();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void selectMatching(String criteria) {
|
||||||
|
Set<IDIYComponent<?>> matching = new HashSet<IDIYComponent<?>>();
|
||||||
|
for (IDIYComponent<?> c : currentProject.getComponents()) {
|
||||||
|
if ((c.getName() != null && c.getName().toLowerCase().matches(criteria.toLowerCase())) ||
|
||||||
|
(c.getValueForDisplay() != null && c.getValueForDisplay().toLowerCase().matches(criteria.toLowerCase())))
|
||||||
|
matching.add(c);
|
||||||
|
}
|
||||||
|
updateSelection(matching);
|
||||||
|
messageDispatcher.dispatchMessage(EventType.REPAINT);
|
||||||
|
messageDispatcher.dispatchMessage(EventType.SCROLL_TO, getSelectionBounds(true));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public VersionNumber getCurrentVersionNumber() {
|
public VersionNumber getCurrentVersionNumber() {
|
||||||
@@ -1924,7 +1937,7 @@ public class Presenter implements IPlugInPort {
|
|||||||
if (ConfigurationManager.getInstance().readBoolean(IPlugInPort.STICKY_POINTS_KEY, true)) {
|
if (ConfigurationManager.getInstance().readBoolean(IPlugInPort.STICKY_POINTS_KEY, true)) {
|
||||||
includeStuckComponents(controlPointMap);
|
includeStuckComponents(controlPointMap);
|
||||||
}
|
}
|
||||||
messageDispatcher.dispatchMessage(EventType.SELECTION_CHANGED, selectedComponents, controlPointMap.keySet());
|
messageDispatcher.dispatchMessage(EventType.SELECTION_CHANGED, selectedComponents, controlPointMap.keySet());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean useNetlistForExpandSelection = false;
|
private static boolean useNetlistForExpandSelection = false;
|
||||||
|
|||||||
@@ -2934,6 +2934,10 @@
|
|||||||
<releaseDate>2020-04-09 00:00:00.000 CET</releaseDate>
|
<releaseDate>2020-04-09 00:00:00.000 CET</releaseDate>
|
||||||
<name></name>
|
<name></name>
|
||||||
<changes>
|
<changes>
|
||||||
|
<org.diylc.appframework.update.Change>
|
||||||
|
<changeType>NEW_FEATURE</changeType>
|
||||||
|
<description>Added "Find" functionality that locates and selects component(s) matching the search text</description>
|
||||||
|
</org.diylc.appframework.update.Change>
|
||||||
<org.diylc.appframework.update.Change>
|
<org.diylc.appframework.update.Change>
|
||||||
<changeType>NEW_FEATURE</changeType>
|
<changeType>NEW_FEATURE</changeType>
|
||||||
<description>Added "Tag Strip" component for point-to-point layouts</description>
|
<description>Added "Tag Strip" component for point-to-point layouts</description>
|
||||||
|
|||||||
Binary file not shown.
@@ -73,13 +73,14 @@ import org.diylc.swing.gui.DialogFactory;
|
|||||||
import org.diylc.swing.gui.editor.PropertyEditorDialog;
|
import org.diylc.swing.gui.editor.PropertyEditorDialog;
|
||||||
import org.diylc.swing.plugins.config.ConfigPlugin;
|
import org.diylc.swing.plugins.config.ConfigPlugin;
|
||||||
import org.diylc.swing.plugins.edit.ComponentTransferable;
|
import org.diylc.swing.plugins.edit.ComponentTransferable;
|
||||||
|
import org.diylc.swing.plugins.edit.FindDialog;
|
||||||
import org.diylc.swing.plugins.file.BomDialog;
|
import org.diylc.swing.plugins.file.BomDialog;
|
||||||
import org.diylc.swing.plugins.file.FileFilterEnum;
|
import org.diylc.swing.plugins.file.FileFilterEnum;
|
||||||
import org.diylc.swingframework.ButtonDialog;
|
import org.diylc.swingframework.ButtonDialog;
|
||||||
import org.diylc.swingframework.CheckBoxListDialog;
|
import org.diylc.swingframework.CheckBoxListDialog;
|
||||||
import org.diylc.swingframework.IDrawingProvider;
|
import org.diylc.swingframework.IDrawingProvider;
|
||||||
import org.diylc.swingframework.export.DrawingExporter;
|
|
||||||
import org.diylc.swingframework.TextDialog;
|
import org.diylc.swingframework.TextDialog;
|
||||||
|
import org.diylc.swingframework.export.DrawingExporter;
|
||||||
import org.diylc.utils.BomEntry;
|
import org.diylc.utils.BomEntry;
|
||||||
|
|
||||||
import com.thoughtworks.xstream.XStream;
|
import com.thoughtworks.xstream.XStream;
|
||||||
@@ -231,6 +232,10 @@ public class ActionFactory {
|
|||||||
public NudgeAction createNudgeAction(IPlugInPort plugInPort) {
|
public NudgeAction createNudgeAction(IPlugInPort plugInPort) {
|
||||||
return new NudgeAction(plugInPort);
|
return new NudgeAction(plugInPort);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public FindAction createFindAction(IPlugInPort plugInPort, ISwingUI swingUI) {
|
||||||
|
return new FindAction(plugInPort, swingUI);
|
||||||
|
}
|
||||||
|
|
||||||
// Config actions.
|
// Config actions.
|
||||||
|
|
||||||
@@ -1545,6 +1550,38 @@ public class ActionFactory {
|
|||||||
plugInPort.bringSelectionToFront();
|
plugInPort.bringSelectionToFront();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class FindAction extends AbstractAction {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private IPlugInPort plugInPort;
|
||||||
|
private ISwingUI swingUI;
|
||||||
|
|
||||||
|
public FindAction(IPlugInPort plugInPort, ISwingUI swingUI) {
|
||||||
|
super();
|
||||||
|
this.plugInPort = plugInPort;
|
||||||
|
this.swingUI = swingUI;
|
||||||
|
putValue(AbstractAction.NAME, "Find");
|
||||||
|
putValue(AbstractAction.SMALL_ICON, IconLoader.SearchBox.getIcon());
|
||||||
|
putValue(AbstractAction.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_F, ActionEvent.CTRL_MASK));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
LOG.info("Find triggered");
|
||||||
|
FindDialog dialog = DialogFactory.getInstance().createFindDialog();
|
||||||
|
dialog.setVisible(true);
|
||||||
|
|
||||||
|
if (dialog.getSelectedButtonCaption() == FindDialog.OK) {
|
||||||
|
String criteria = dialog.getCriteria();
|
||||||
|
plugInPort.selectMatching(criteria);
|
||||||
|
if (plugInPort.getSelectedComponents().size() == 0) {
|
||||||
|
swingUI.showMessage("No matching components found.", "Find", ISwingUI.INFORMATION_MESSAGE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static class ConfigAction extends AbstractAction {
|
public static class ConfigAction extends AbstractAction {
|
||||||
|
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ import org.diylc.swing.plugins.cloud.view.ChangePasswordDialog;
|
|||||||
import org.diylc.swing.plugins.cloud.view.LoginDialog;
|
import org.diylc.swing.plugins.cloud.view.LoginDialog;
|
||||||
import org.diylc.swing.plugins.cloud.view.UploadDialog;
|
import org.diylc.swing.plugins.cloud.view.UploadDialog;
|
||||||
import org.diylc.swing.plugins.cloud.view.UserEditDialog;
|
import org.diylc.swing.plugins.cloud.view.UserEditDialog;
|
||||||
|
import org.diylc.swing.plugins.edit.FindDialog;
|
||||||
import org.diylc.swing.plugins.file.BomDialog;
|
import org.diylc.swing.plugins.file.BomDialog;
|
||||||
import org.diylc.swingframework.AboutDialog;
|
import org.diylc.swingframework.AboutDialog;
|
||||||
import org.diylc.swingframework.IFileChooserAccessory;
|
import org.diylc.swingframework.IFileChooserAccessory;
|
||||||
@@ -196,6 +197,11 @@ public class DialogFactory {
|
|||||||
LoginDialog dialog = new LoginDialog(mainFrame);
|
LoginDialog dialog = new LoginDialog(mainFrame);
|
||||||
return dialog;
|
return dialog;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public FindDialog createFindDialog() {
|
||||||
|
FindDialog dialog = new FindDialog(mainFrame);
|
||||||
|
return dialog;
|
||||||
|
}
|
||||||
|
|
||||||
public UploadDialog createUploadDialog(JFrame ownerFrame, IPlugInPort plugInPort, String[] categories,
|
public UploadDialog createUploadDialog(JFrame ownerFrame, IPlugInPort plugInPort, String[] categories,
|
||||||
boolean isUpdate) {
|
boolean isUpdate) {
|
||||||
|
|||||||
@@ -706,7 +706,7 @@ public class CanvasPlugin implements IPlugIn, ClipboardOwner {
|
|||||||
|
|
||||||
@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, EventType.SCROLL_TO);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("incomplete-switch")
|
@SuppressWarnings("incomplete-switch")
|
||||||
@@ -759,6 +759,12 @@ public class CanvasPlugin implements IPlugIn, ClipboardOwner {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
case SCROLL_TO:
|
||||||
|
Rectangle visibleRect2 = canvasPanel.getVisibleRect();
|
||||||
|
Rectangle2D targetRect = (Rectangle2D) params[0];
|
||||||
|
canvasPanel.scrollRectToVisible(new Rectangle((int)(targetRect.getCenterX() - visibleRect2.width / 2),
|
||||||
|
(int)(targetRect.getCenterY() - visibleRect2.height / 2), visibleRect2.width, visibleRect2.height));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
// }
|
// }
|
||||||
// });
|
// });
|
||||||
|
|||||||
@@ -74,7 +74,8 @@ public class EditMenuPlugin implements IPlugIn, ClipboardOwner {
|
|||||||
private ActionFactory.RotateSelectionAction rotateClockwiseAction;
|
private ActionFactory.RotateSelectionAction rotateClockwiseAction;
|
||||||
private ActionFactory.RotateSelectionAction rotateCounterClockwiseAction;
|
private ActionFactory.RotateSelectionAction rotateCounterClockwiseAction;
|
||||||
private ActionFactory.MirrorSelectionAction mirrorHorizontallyAction;
|
private ActionFactory.MirrorSelectionAction mirrorHorizontallyAction;
|
||||||
private ActionFactory.MirrorSelectionAction mirrorVerticallyAction;
|
private ActionFactory.MirrorSelectionAction mirrorVerticallyAction;
|
||||||
|
private ActionFactory.FindAction findAction;
|
||||||
|
|
||||||
private UndoHandler<Project> undoHandler;
|
private UndoHandler<Project> undoHandler;
|
||||||
|
|
||||||
@@ -261,6 +262,12 @@ public class EditMenuPlugin implements IPlugIn, ClipboardOwner {
|
|||||||
ActionFactory.getInstance().createMirrorSelectionAction(plugInPort, IComponentTransformer.VERTICAL);
|
ActionFactory.getInstance().createMirrorSelectionAction(plugInPort, IComponentTransformer.VERTICAL);
|
||||||
}
|
}
|
||||||
return mirrorVerticallyAction;
|
return mirrorVerticallyAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ActionFactory.FindAction getFindAction() {
|
||||||
|
if (findAction == null)
|
||||||
|
findAction = ActionFactory.getInstance().createFindAction(plugInPort, swingUI);
|
||||||
|
return findAction;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -276,7 +283,8 @@ public class EditMenuPlugin implements IPlugIn, ClipboardOwner {
|
|||||||
swingUI.injectMenuAction(getCopyAction(), EDIT_TITLE);
|
swingUI.injectMenuAction(getCopyAction(), EDIT_TITLE);
|
||||||
swingUI.injectMenuAction(getPasteAction(), EDIT_TITLE);
|
swingUI.injectMenuAction(getPasteAction(), EDIT_TITLE);
|
||||||
swingUI.injectMenuAction(getDuplicateAction(), EDIT_TITLE);
|
swingUI.injectMenuAction(getDuplicateAction(), EDIT_TITLE);
|
||||||
swingUI.injectMenuAction(null, EDIT_TITLE);
|
swingUI.injectMenuAction(null, EDIT_TITLE);
|
||||||
|
swingUI.injectMenuAction(getFindAction(), EDIT_TITLE);
|
||||||
swingUI.injectMenuAction(actionFactory.createSelectAllAction(plugInPort), EDIT_TITLE);
|
swingUI.injectMenuAction(actionFactory.createSelectAllAction(plugInPort), EDIT_TITLE);
|
||||||
swingUI.injectMenuAction(getEditSelectionAction(), EDIT_TITLE);
|
swingUI.injectMenuAction(getEditSelectionAction(), EDIT_TITLE);
|
||||||
swingUI.injectMenuAction(getDeleteSelectionAction(), EDIT_TITLE);
|
swingUI.injectMenuAction(getDeleteSelectionAction(), EDIT_TITLE);
|
||||||
|
|||||||
@@ -0,0 +1,118 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
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.edit;
|
||||||
|
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.awt.GridBagConstraints;
|
||||||
|
import java.awt.GridBagLayout;
|
||||||
|
import java.awt.Insets;
|
||||||
|
|
||||||
|
import javax.swing.BorderFactory;
|
||||||
|
import javax.swing.JButton;
|
||||||
|
import javax.swing.JComponent;
|
||||||
|
import javax.swing.JFrame;
|
||||||
|
import javax.swing.JLabel;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.JTextField;
|
||||||
|
import javax.swing.event.DocumentEvent;
|
||||||
|
import javax.swing.event.DocumentListener;
|
||||||
|
|
||||||
|
import org.diylc.swingframework.ButtonDialog;
|
||||||
|
|
||||||
|
public class FindDialog extends ButtonDialog {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private JPanel mainPanel;
|
||||||
|
|
||||||
|
private JTextField criteriaField;
|
||||||
|
|
||||||
|
private String criteria;
|
||||||
|
|
||||||
|
public FindDialog(JFrame owner) {
|
||||||
|
super(owner, "Find", new String[] {OK, CANCEL});
|
||||||
|
setMinimumSize(new Dimension(240, 32));
|
||||||
|
layoutGui();
|
||||||
|
refreshState();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCriteria() {
|
||||||
|
return criteria;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected JComponent getMainComponent() {
|
||||||
|
if (mainPanel == null) {
|
||||||
|
mainPanel = new JPanel(new GridBagLayout());
|
||||||
|
mainPanel.setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8));
|
||||||
|
|
||||||
|
GridBagConstraints gbc = new GridBagConstraints();
|
||||||
|
gbc.anchor = GridBagConstraints.LINE_START;
|
||||||
|
gbc.fill = GridBagConstraints.NONE;
|
||||||
|
gbc.insets = new Insets(2, 2, 2, 2);
|
||||||
|
|
||||||
|
gbc.gridx = 0;
|
||||||
|
|
||||||
|
gbc.gridy = 0;
|
||||||
|
mainPanel.add(new JLabel("Look for:"), gbc);
|
||||||
|
|
||||||
|
gbc.gridx = 1;
|
||||||
|
gbc.fill = GridBagConstraints.HORIZONTAL;
|
||||||
|
gbc.weightx = 1;
|
||||||
|
|
||||||
|
gbc.gridy = 0;
|
||||||
|
mainPanel.add(getCriteriaField(), gbc);
|
||||||
|
}
|
||||||
|
return mainPanel;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void refreshState() {
|
||||||
|
this.criteria = getCriteriaField().getText();
|
||||||
|
|
||||||
|
JButton okButton = getButton(OK);
|
||||||
|
okButton.setEnabled(this.criteria.length() > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private JTextField getCriteriaField() {
|
||||||
|
if (criteriaField == null) {
|
||||||
|
criteriaField = new JTextField();
|
||||||
|
criteriaField.getDocument().addDocumentListener(new DocumentListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeUpdate(DocumentEvent e) {
|
||||||
|
refreshState();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void insertUpdate(DocumentEvent e) {
|
||||||
|
refreshState();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void changedUpdate(DocumentEvent e) {
|
||||||
|
refreshState();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return criteriaField;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user