diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/CompletionExtender.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/CompletionExtender.java new file mode 100644 index 000000000000..824f89dc6392 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/CompletionExtender.java @@ -0,0 +1,91 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.codeInsight.lookup.impl; + +import com.intellij.codeInsight.lookup.LookupElement; +import com.intellij.ui.HeavyweightHint; +import com.intellij.ui.HintHint; +import com.intellij.util.ui.UIUtil; +import org.jetbrains.annotations.NotNull; + +import javax.swing.*; +import java.awt.*; + +/** + * @author Konstantin Bulenkov + */ +public class CompletionExtender extends HeavyweightHint { + private LookupElement myElement; + @NotNull private LookupImpl myLookup; + private int myIndex; + + public CompletionExtender(@NotNull LookupElement element, @NotNull LookupImpl lookup) { + super(createComponent(element, lookup), false); + myElement = element; + myLookup = lookup; + myIndex = myLookup.getList().getSelectedIndex(); + } + + public LookupElement getLookupElement() { + return myElement; + } + + public boolean sameAsFor(LookupElement item) { + return getLookupElement().equals(item) + && myIndex == myLookup.getList().getSelectedIndex(); + } + + private static JComponent createComponent(LookupElement element, LookupImpl lookup) { + final LookupCellRenderer renderer = new LookupCellRenderer(lookup); + renderer.setFullSize(true); + final JComponent component = (JComponent)renderer.getListCellRendererComponent(lookup.getList(), element, + lookup.getList().getSelectedIndex(), + true, false); + component.setSize(component.getPreferredSize()); + return component; + } + + public boolean show() { + final JList list = myLookup.getList(); + if (getComponent().getWidth() > list.getWidth()) { + final JComponent rootPane = UIUtil.getRootPane(myLookup.getEditor().getContentComponent()); + + final Point p = list.getLocationOnScreen(); + p.y += list.indexToLocation(list.getSelectedIndex()).y; + SwingUtilities.convertPointFromScreen(p, rootPane); + + if (rootPane != null) { + show(rootPane, p.x, p.y, null, new HintHint(rootPane, p)); + return true; + } + } + return false; + } + + private static Point getPoint(JList list, JComponent rootPane) { + final Point p = list.getLocationOnScreen(); + p.y += list.indexToLocation(list.getSelectedIndex()).y; + SwingUtilities.convertPointFromScreen(p, rootPane); + return p; + } + + @Override + public void hide() { + super.hide(); + myLookup = null; + myElement = null; + } +} diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java index b11b7ef36300..a7c31b5a67dc 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java @@ -95,7 +95,7 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable private final Project myProject; private final Editor myEditor; - private Hint tip; + private CompletionExtender extender; private String myInitialPrefix; private boolean myStableStart; @@ -1029,10 +1029,6 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable public void valueChanged(ListSelectionEvent e){ myHintAlarm.cancelAllRequests(); - if (tip != null && tip.isVisible()) { - tip.hide(); - } - final LookupElement item = getCurrentItem(); if (oldItem != item) { mySelectionInvariant = item == null ? null : myPresentableModel.getItemPresentationInvariant(item); @@ -1043,26 +1039,18 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable } if (item != null) { updateHint(item); - if (myList.getModel().getSize() > 1 && isVisible()) { - final LookupCellRenderer renderer = new LookupCellRenderer(LookupImpl.this); - renderer.setFullSize(true); - final JComponent component = (JComponent)renderer.getListCellRendererComponent(myList, item, - myList - .getSelectedIndex(), - true, false); - component.setSize(component.getPreferredSize()); - if (component.getWidth() > myList.getWidth()) { - tip = new HeavyweightHint(component, false); - final Point p = myList.getLocationOnScreen(); - p.y += myList.indexToLocation(myList.getSelectedIndex()).y; + } + oldItem = item; - final JComponent editor = UIUtil.getRootPane(myEditor.getContentComponent()); - SwingUtilities.convertPointFromScreen(p, editor); - tip.show(editor, p.x, p.y, null, new HintHint(editor, p)); + if (item != null && LookupImpl.this.isVisible()) { + if (extender == null || !extender.isVisible() || !extender.sameAsFor(item)) { + if (extender != null) extender.hide(); + extender = new CompletionExtender(item, LookupImpl.this); + if (!extender.show()) { + extender.hide(); } } } - oldItem = item; } }); @@ -1390,8 +1378,8 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable } Disposer.dispose(myProcessIcon); Disposer.dispose(myHintAlarm); - if (tip != null) { - tip.hide(); + if (extender != null) { + extender.hide(); } myDisposed = true; disposeTrace = DebugUtil.currentStackTrace() + "\n============";