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.
|
||||
*/
|
||||
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 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 {
|
||||
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);
|
||||
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
|
||||
public VersionNumber getCurrentVersionNumber() {
|
||||
@@ -1924,7 +1937,7 @@ public class Presenter implements IPlugInPort {
|
||||
if (ConfigurationManager.getInstance().readBoolean(IPlugInPort.STICKY_POINTS_KEY, true)) {
|
||||
includeStuckComponents(controlPointMap);
|
||||
}
|
||||
messageDispatcher.dispatchMessage(EventType.SELECTION_CHANGED, selectedComponents, controlPointMap.keySet());
|
||||
messageDispatcher.dispatchMessage(EventType.SELECTION_CHANGED, selectedComponents, controlPointMap.keySet());
|
||||
}
|
||||
|
||||
private static boolean useNetlistForExpandSelection = false;
|
||||
|
||||
@@ -2934,6 +2934,10 @@
|
||||
<releaseDate>2020-04-09 00:00:00.000 CET</releaseDate>
|
||||
<name></name>
|
||||
<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>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<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.plugins.config.ConfigPlugin;
|
||||
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.FileFilterEnum;
|
||||
import org.diylc.swingframework.ButtonDialog;
|
||||
import org.diylc.swingframework.CheckBoxListDialog;
|
||||
import org.diylc.swingframework.IDrawingProvider;
|
||||
import org.diylc.swingframework.export.DrawingExporter;
|
||||
import org.diylc.swingframework.TextDialog;
|
||||
import org.diylc.swingframework.export.DrawingExporter;
|
||||
import org.diylc.utils.BomEntry;
|
||||
|
||||
import com.thoughtworks.xstream.XStream;
|
||||
@@ -231,6 +232,10 @@ public class ActionFactory {
|
||||
public NudgeAction createNudgeAction(IPlugInPort plugInPort) {
|
||||
return new NudgeAction(plugInPort);
|
||||
}
|
||||
|
||||
public FindAction createFindAction(IPlugInPort plugInPort, ISwingUI swingUI) {
|
||||
return new FindAction(plugInPort, swingUI);
|
||||
}
|
||||
|
||||
// Config actions.
|
||||
|
||||
@@ -1545,6 +1550,38 @@ public class ActionFactory {
|
||||
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 {
|
||||
|
||||
|
||||
@@ -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.UploadDialog;
|
||||
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.swingframework.AboutDialog;
|
||||
import org.diylc.swingframework.IFileChooserAccessory;
|
||||
@@ -196,6 +197,11 @@ public class DialogFactory {
|
||||
LoginDialog dialog = new LoginDialog(mainFrame);
|
||||
return dialog;
|
||||
}
|
||||
|
||||
public FindDialog createFindDialog() {
|
||||
FindDialog dialog = new FindDialog(mainFrame);
|
||||
return dialog;
|
||||
}
|
||||
|
||||
public UploadDialog createUploadDialog(JFrame ownerFrame, IPlugInPort plugInPort, String[] categories,
|
||||
boolean isUpdate) {
|
||||
|
||||
@@ -706,7 +706,7 @@ public class CanvasPlugin implements IPlugIn, ClipboardOwner {
|
||||
|
||||
@Override
|
||||
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")
|
||||
@@ -759,6 +759,12 @@ public class CanvasPlugin implements IPlugIn, ClipboardOwner {
|
||||
}
|
||||
});
|
||||
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 rotateCounterClockwiseAction;
|
||||
private ActionFactory.MirrorSelectionAction mirrorHorizontallyAction;
|
||||
private ActionFactory.MirrorSelectionAction mirrorVerticallyAction;
|
||||
private ActionFactory.MirrorSelectionAction mirrorVerticallyAction;
|
||||
private ActionFactory.FindAction findAction;
|
||||
|
||||
private UndoHandler<Project> undoHandler;
|
||||
|
||||
@@ -261,6 +262,12 @@ public class EditMenuPlugin implements IPlugIn, ClipboardOwner {
|
||||
ActionFactory.getInstance().createMirrorSelectionAction(plugInPort, IComponentTransformer.VERTICAL);
|
||||
}
|
||||
return mirrorVerticallyAction;
|
||||
}
|
||||
|
||||
public ActionFactory.FindAction getFindAction() {
|
||||
if (findAction == null)
|
||||
findAction = ActionFactory.getInstance().createFindAction(plugInPort, swingUI);
|
||||
return findAction;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -276,7 +283,8 @@ public class EditMenuPlugin implements IPlugIn, ClipboardOwner {
|
||||
swingUI.injectMenuAction(getCopyAction(), EDIT_TITLE);
|
||||
swingUI.injectMenuAction(getPasteAction(), 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(getEditSelectionAction(), 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