This is an automated email from the ASF dual-hosted git repository. ebakke pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/netbeans.git
The following commit(s) were added to refs/heads/master by this push: new 27c9f3ba08 Added CompletionItem.shouldSingleClickInvokeDefaultAction to the Editor Completion API. 27c9f3ba08 is described below commit 27c9f3ba08cdff765b95639f7db815b34468247e Author: Eirik Bakke <eba...@ultorg.com> AuthorDate: Sat Oct 1 10:21:15 2022 -0400 Added CompletionItem.shouldSingleClickInvokeDefaultAction to the Editor Completion API. --- ide/editor.completion/apichanges.xml | 18 ++++ .../editor/completion/CompletionLayout.java | 108 ++++++++++++++------- .../spi/editor/completion/CompletionItem.java | 8 ++ 3 files changed, 97 insertions(+), 37 deletions(-) diff --git a/ide/editor.completion/apichanges.xml b/ide/editor.completion/apichanges.xml index 92daa525f7..4fe52d6c7b 100644 --- a/ide/editor.completion/apichanges.xml +++ b/ide/editor.completion/apichanges.xml @@ -84,6 +84,24 @@ is the proper place. <!-- ACTUAL CHANGES BEGIN HERE: --> <changes> + <change id="CompletionItem.shouldSingleClickInvokeDefaultAction"> + <api name="completion"/> + <summary>Addition of optional CompletionItem.shouldSingleClickInvokeDefaultAction() method</summary> + <version major="1" minor="65"/> + <date day="20" month="1" year="2023"/> + <author login="ebakke"/> + <compatibility addition="yes"/> + <description> + <p> + <code>CompletionItem.shouldSingleClickInvokeDefaultAction</code> method was added + to to indicate that a single mouse click on the <code>CompletionItem</code> in the + completion list, rather than only a double-click, will invoke its default action. + A default method is provided in the method which returns false, preserving the old + behavior by default. + </p> + </description> + </change> + <change id="CompletionUtilities.newCompletionItemBuilder"> <api name="completion"/> <summary>Addition of CompletionUtilities.newCompletionItemBuilder() method</summary> diff --git a/ide/editor.completion/src/org/netbeans/modules/editor/completion/CompletionLayout.java b/ide/editor.completion/src/org/netbeans/modules/editor/completion/CompletionLayout.java index 43303cae6b..1486334cb7 100644 --- a/ide/editor.completion/src/org/netbeans/modules/editor/completion/CompletionLayout.java +++ b/ide/editor.completion/src/org/netbeans/modules/editor/completion/CompletionLayout.java @@ -367,48 +367,82 @@ public final class CompletionLayout { completionScrollPane = new CompletionScrollPane( editorComponent, listSelectionListener, new MouseAdapter() { + CompletionItem selectedItemOnPress; + + @Override + public void mousePressed(MouseEvent evt) { + if (!SwingUtilities.isLeftMouseButton(evt)) { + return; + } + selectedItemOnPress = completionScrollPane.getSelectedCompletionItem(); + } + + @Override + public void mouseReleased(MouseEvent evt) { + /* Handle single-click via mouseReleased, rather than in mouseClick with + getClickCount() == 1, since the latter kind of event will not be fired if + the mouse pointer ends up being dragged a tiny bit while the button is + clicked (common on touchpads). */ + if (!SwingUtilities.isLeftMouseButton(evt)) { + return; + } + CompletionItem selectedItem = completionScrollPane.getSelectedCompletionItem(); + boolean shouldInvokeDefaultAction = + selectedItem != null && selectedItem == selectedItemOnPress && + selectedItem.shouldSingleClickInvokeDefaultAction(); + selectedItemOnPress = null; + if (shouldInvokeDefaultAction) { + invokeDefaultAction(selectedItem); + } + } + @Override public void mouseClicked(MouseEvent evt) { - JTextComponent c = getEditorComponent(); - if (SwingUtilities.isLeftMouseButton(evt)) { - if (completionScrollPane.getView().getSize().width - CompletionJList.arrowSpan() <= evt.getPoint().x) { - CompletionItem selectedItem = completionScrollPane.getSelectedCompletionItem(); - if (selectedItem instanceof CompositeCompletionItem && !((CompositeCompletionItem)selectedItem).getSubItems().isEmpty()) { - CompletionImpl.get().showCompletionSubItems(); - evt.consume(); - return; - } + if (!SwingUtilities.isLeftMouseButton(evt)) { + return; + } + if (completionScrollPane.getView().getSize().width - CompletionJList.arrowSpan() <= evt.getPoint().x) { + CompletionItem selectedItem = completionScrollPane.getSelectedCompletionItem(); + if (selectedItem instanceof CompositeCompletionItem && !((CompositeCompletionItem)selectedItem).getSubItems().isEmpty()) { + CompletionImpl.get().showCompletionSubItems(); + evt.consume(); + return; } - for (CompletionLayoutPopup popup : getLayout().visiblePopups) { - if (popup instanceof CompletionPopup) { - if (popup == CompletionPopup.this) { - break; - } else { - popup.hide(); - } + } + for (CompletionLayoutPopup popup : getLayout().visiblePopups) { + if (popup instanceof CompletionPopup) { + if (popup == CompletionPopup.this) { + break; + } else { + popup.hide(); } } - if (c != null && evt.getClickCount() == 2 ) { - CompletionItem selectedItem - = completionScrollPane.getSelectedCompletionItem(); - if (selectedItem != null) { - Document doc = c.getDocument(); - if (doc instanceof GuardedDocument && ((GuardedDocument)doc).isPosGuarded(c.getSelectionEnd())) { - Toolkit.getDefaultToolkit().beep(); - } else { - LogRecord r = new LogRecord(Level.FINE, "COMPL_MOUSE_SELECT"); // NOI18N - r.setParameters(new Object[] { null, completionScrollPane.getSelectedIndex(), selectedItem.getClass().getSimpleName()}); - CompletionImpl.uilog(r); - CompletionImpl.sendUndoableEdit(doc, CloneableEditorSupport.BEGIN_COMMIT_GROUP); - MulticaretHandler mch = MulticaretHandler.create(c); - try { - selectedItem.defaultAction(c); - } finally { - mch.release(); - CompletionImpl.sendUndoableEdit(doc, CloneableEditorSupport.END_COMMIT_GROUP); - } - } - } + } + CompletionItem selectedItem = completionScrollPane.getSelectedCompletionItem(); + if (selectedItem != null && !selectedItem.shouldSingleClickInvokeDefaultAction() && evt.getClickCount() == 2) { + invokeDefaultAction(selectedItem); + } + } + + private void invokeDefaultAction(CompletionItem selectedItem) { + JTextComponent c = getEditorComponent(); + if (c == null ) { + return; + } + Document doc = c.getDocument(); + if (doc instanceof GuardedDocument && ((GuardedDocument)doc).isPosGuarded(c.getSelectionEnd())) { + Toolkit.getDefaultToolkit().beep(); + } else { + LogRecord r = new LogRecord(Level.FINE, "COMPL_MOUSE_SELECT"); // NOI18N + r.setParameters(new Object[] { null, completionScrollPane.getSelectedIndex(), selectedItem.getClass().getSimpleName()}); + CompletionImpl.uilog(r); + CompletionImpl.sendUndoableEdit(doc, CloneableEditorSupport.BEGIN_COMMIT_GROUP); + MulticaretHandler mch = MulticaretHandler.create(c); + try { + selectedItem.defaultAction(c); + } finally { + mch.release(); + CompletionImpl.sendUndoableEdit(doc, CloneableEditorSupport.END_COMMIT_GROUP); } } } diff --git a/ide/editor.completion/src/org/netbeans/spi/editor/completion/CompletionItem.java b/ide/editor.completion/src/org/netbeans/spi/editor/completion/CompletionItem.java index a464f86b15..04b4d196d0 100644 --- a/ide/editor.completion/src/org/netbeans/spi/editor/completion/CompletionItem.java +++ b/ide/editor.completion/src/org/netbeans/spi/editor/completion/CompletionItem.java @@ -51,6 +51,14 @@ public interface CompletionItem { */ void defaultAction(JTextComponent component); + /** + * Indicate if single-clicking the item in the completion list should invoke the default action. + * Normally a double-click is required. + */ + default boolean shouldSingleClickInvokeDefaultAction() { + return false; + } + /** * Process the key pressed when this completion item was selected * in the completion popup window. --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@netbeans.apache.org For additional commands, e-mail: commits-h...@netbeans.apache.org For further information about the NetBeans mailing lists, visit: https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists