Lines 48-53
Link Here
|
48 |
import java.awt.Color; |
48 |
import java.awt.Color; |
49 |
import java.awt.Dimension; |
49 |
import java.awt.Dimension; |
50 |
import java.awt.EventQueue; |
50 |
import java.awt.EventQueue; |
|
|
51 |
import java.awt.Point; |
51 |
import java.awt.Rectangle; |
52 |
import java.awt.Rectangle; |
52 |
import java.awt.Toolkit; |
53 |
import java.awt.Toolkit; |
53 |
import java.awt.event.ActionEvent; |
54 |
import java.awt.event.ActionEvent; |
Lines 56-63
Link Here
|
56 |
import java.awt.event.MouseEvent; |
57 |
import java.awt.event.MouseEvent; |
57 |
import java.lang.ref.Reference; |
58 |
import java.lang.ref.Reference; |
58 |
import java.lang.ref.WeakReference; |
59 |
import java.lang.ref.WeakReference; |
|
|
60 |
import java.util.LinkedList; |
59 |
import java.util.List; |
61 |
import java.util.List; |
60 |
import java.util.Stack; |
|
|
61 |
import java.util.logging.Level; |
62 |
import java.util.logging.Level; |
62 |
import java.util.logging.LogRecord; |
63 |
import java.util.logging.LogRecord; |
63 |
import javax.swing.Action; |
64 |
import javax.swing.Action; |
Lines 75-80
Link Here
|
75 |
import org.netbeans.editor.GuardedDocument; |
76 |
import org.netbeans.editor.GuardedDocument; |
76 |
import org.netbeans.spi.editor.completion.CompletionDocumentation; |
77 |
import org.netbeans.spi.editor.completion.CompletionDocumentation; |
77 |
import org.netbeans.spi.editor.completion.CompletionItem; |
78 |
import org.netbeans.spi.editor.completion.CompletionItem; |
|
|
79 |
import org.netbeans.spi.editor.completion.CompositeCompletionItem; |
78 |
import org.openide.text.CloneableEditorSupport; |
80 |
import org.openide.text.CloneableEditorSupport; |
79 |
import org.openide.util.NbBundle; |
81 |
import org.openide.util.NbBundle; |
80 |
|
82 |
|
Lines 105-111
Link Here
|
105 |
private final DocPopup docPopup; |
107 |
private final DocPopup docPopup; |
106 |
private final TipPopup tipPopup; |
108 |
private final TipPopup tipPopup; |
107 |
|
109 |
|
108 |
private Stack<CompletionLayoutPopup> visiblePopups; |
110 |
private LinkedList<CompletionLayoutPopup> visiblePopups; |
109 |
|
111 |
|
110 |
CompletionLayout() { |
112 |
CompletionLayout() { |
111 |
completionPopup = new CompletionPopup(); |
113 |
completionPopup = new CompletionPopup(); |
Lines 117-123
Link Here
|
117 |
tipPopup = new TipPopup(); |
119 |
tipPopup = new TipPopup(); |
118 |
tipPopup.setLayout(this); |
120 |
tipPopup.setLayout(this); |
119 |
tipPopup.setPreferDisplayAboveCaret(true); |
121 |
tipPopup.setPreferDisplayAboveCaret(true); |
120 |
visiblePopups = new Stack<CompletionLayoutPopup>(); |
122 |
visiblePopups = new LinkedList<CompletionLayoutPopup>(); |
121 |
} |
123 |
} |
122 |
|
124 |
|
123 |
public JTextComponent getEditorComponent() { |
125 |
public JTextComponent getEditorComponent() { |
Lines 132-140
Link Here
|
132 |
} |
134 |
} |
133 |
|
135 |
|
134 |
private void hideAll() { |
136 |
private void hideAll() { |
135 |
completionPopup.hide(); |
137 |
for (CompletionLayoutPopup popup : visiblePopups) { |
136 |
docPopup.hide(); |
138 |
popup.hide(); |
137 |
tipPopup.hide(); |
139 |
} |
138 |
visiblePopups.clear(); |
140 |
visiblePopups.clear(); |
139 |
} |
141 |
} |
140 |
|
142 |
|
Lines 145-159
Link Here
|
145 |
visiblePopups.push(completionPopup); |
147 |
visiblePopups.push(completionPopup); |
146 |
} |
148 |
} |
147 |
|
149 |
|
|
|
150 |
public void showCompletionSubItems() { |
151 |
CompletionItem item = getSelectedCompletionItem(); |
152 |
List<? extends CompletionItem> subItems = item instanceof CompositeCompletionItem ? ((CompositeCompletionItem)item).getSubItems() : null; |
153 |
if (subItems != null && !subItems.isEmpty()) { |
154 |
Point p = getSelectedLocation(); |
155 |
if (p != null) { |
156 |
CompletionPopup popup = new CompletionPopup(); |
157 |
popup.setLayout(this); |
158 |
popup.show(subItems, p); |
159 |
if (!visiblePopups.contains(popup)) |
160 |
visiblePopups.push(popup); |
161 |
} |
162 |
} |
163 |
} |
164 |
|
148 |
public boolean hideCompletion() { |
165 |
public boolean hideCompletion() { |
149 |
if (completionPopup.isVisible()) { |
166 |
for (CompletionLayoutPopup popup : visiblePopups) { |
150 |
completionPopup.hide(); |
167 |
if (popup instanceof CompletionPopup && popup.isVisible()) { |
151 |
completionPopup.completionScrollPane = null; |
168 |
popup.hide(); |
152 |
visiblePopups.remove(completionPopup); |
169 |
((CompletionPopup)popup).completionScrollPane = null; |
153 |
return true; |
170 |
visiblePopups.remove(popup); |
154 |
} else { // not visible |
171 |
return true; |
155 |
return false; |
172 |
} |
156 |
} |
173 |
} |
|
|
174 |
return false; |
157 |
} |
175 |
} |
158 |
|
176 |
|
159 |
public boolean isCompletionVisible() { |
177 |
public boolean isCompletionVisible() { |
Lines 161-176
Link Here
|
161 |
} |
179 |
} |
162 |
|
180 |
|
163 |
public CompletionItem getSelectedCompletionItem() { |
181 |
public CompletionItem getSelectedCompletionItem() { |
164 |
return completionPopup.getSelectedCompletionItem(); |
182 |
for (CompletionLayoutPopup popup : visiblePopups) { |
|
|
183 |
if (popup instanceof CompletionPopup && popup.isVisible()) { |
184 |
return ((CompletionPopup)popup).getSelectedCompletionItem(); |
185 |
} |
186 |
} |
187 |
return null; |
165 |
} |
188 |
} |
166 |
|
189 |
|
167 |
public int getSelectedIndex() { |
190 |
public int getSelectedIndex() { |
168 |
return completionPopup.getSelectedIndex(); |
191 |
for (CompletionLayoutPopup popup : visiblePopups) { |
|
|
192 |
if (popup instanceof CompletionPopup && popup.isVisible()) { |
193 |
return ((CompletionPopup)popup).getSelectedIndex(); |
194 |
} |
195 |
} |
196 |
return -1; |
197 |
} |
198 |
|
199 |
public Point getSelectedLocation() { |
200 |
for (CompletionLayoutPopup popup : visiblePopups) { |
201 |
if (popup instanceof CompletionPopup && popup.isVisible()) { |
202 |
return ((CompletionPopup)popup).getSelectedLocation(); |
203 |
} |
204 |
} |
205 |
return null; |
169 |
} |
206 |
} |
170 |
|
207 |
|
171 |
public void processKeyEvent(KeyEvent evt) { |
208 |
public void processKeyEvent(KeyEvent evt) { |
172 |
for (int i = visiblePopups.size() - 1; i >= 0; i--) { |
209 |
for (CompletionLayoutPopup popup : visiblePopups) { |
173 |
CompletionLayoutPopup popup = visiblePopups.get(i); |
|
|
174 |
popup.processKeyEvent(evt); |
210 |
popup.processKeyEvent(evt); |
175 |
if (evt.isConsumed()) |
211 |
if (evt.isConsumed()) |
176 |
return; |
212 |
return; |
Lines 271-277
Link Here
|
271 |
) { |
307 |
) { |
272 |
updateLayout(docPopup); |
308 |
updateLayout(docPopup); |
273 |
} |
309 |
} |
274 |
|
|
|
275 |
} else if (popup == docPopup) { // documentation popup |
310 |
} else if (popup == docPopup) { // documentation popup |
276 |
if (isCompletionVisible()) { |
311 |
if (isCompletionVisible()) { |
277 |
// Documentation must sync anchoring with completion |
312 |
// Documentation must sync anchoring with completion |
Lines 294-299
Link Here
|
294 |
// docPopup layout will be handled as part of completion popup layout |
329 |
// docPopup layout will be handled as part of completion popup layout |
295 |
updateLayout(completionPopup); |
330 |
updateLayout(completionPopup); |
296 |
} |
331 |
} |
|
|
332 |
} else { // completion sub-items popup |
333 |
Rectangle occupiedBounds = popup.getAnchorOffsetBounds(); |
334 |
popup.showAlongOrNextOccupiedBounds(occupiedBounds, occupiedBounds); |
297 |
} |
335 |
} |
298 |
} |
336 |
} |
299 |
|
337 |
|
Lines 313-320
Link Here
|
313 |
|
351 |
|
314 |
private CompletionScrollPane completionScrollPane; |
352 |
private CompletionScrollPane completionScrollPane; |
315 |
|
353 |
|
|
|
354 |
public void show(List data, Point location) { |
355 |
show(data, null, -1, location, null, null, null, 0); |
356 |
} |
357 |
|
316 |
public void show(List data, String title, int anchorOffset, |
358 |
public void show(List data, String title, int anchorOffset, |
317 |
ListSelectionListener listSelectionListener, String additionalItemsText, String shortcutHint, int selectedIndex) { |
359 |
ListSelectionListener listSelectionListener, String additionalItemsText, String shortcutHint, int selectedIndex) { |
|
|
360 |
show(data, title, anchorOffset, null, listSelectionListener, additionalItemsText, shortcutHint, selectedIndex); |
361 |
} |
362 |
|
363 |
private void show(List data, String title, int anchorOffset, Point location, |
364 |
ListSelectionListener listSelectionListener, String additionalItemsText, String shortcutHint, int selectedIndex) { |
318 |
|
365 |
|
319 |
JTextComponent editorComponent = getEditorComponent(); |
366 |
JTextComponent editorComponent = getEditorComponent(); |
320 |
if (editorComponent == null) { |
367 |
if (editorComponent == null) { |
Lines 338-343
Link Here
|
338 |
public void mouseClicked(MouseEvent evt) { |
385 |
public void mouseClicked(MouseEvent evt) { |
339 |
JTextComponent c = getEditorComponent(); |
386 |
JTextComponent c = getEditorComponent(); |
340 |
if (SwingUtilities.isLeftMouseButton(evt)) { |
387 |
if (SwingUtilities.isLeftMouseButton(evt)) { |
|
|
388 |
if (completionScrollPane.getView().getSize().width - CompletionJList.arrowSpan() <= evt.getPoint().x) { |
389 |
CompletionItem selectedItem = completionScrollPane.getSelectedCompletionItem(); |
390 |
if (selectedItem instanceof CompositeCompletionItem && !((CompositeCompletionItem)selectedItem).getSubItems().isEmpty()) { |
391 |
CompletionImpl.get().showCompletionSubItems(); |
392 |
evt.consume(); |
393 |
return; |
394 |
} |
395 |
} |
396 |
for (CompletionLayoutPopup popup : getLayout().visiblePopups) { |
397 |
if (popup instanceof CompletionPopup) { |
398 |
if (popup == CompletionPopup.this) { |
399 |
break; |
400 |
} else { |
401 |
popup.hide(); |
402 |
} |
403 |
} |
404 |
} |
341 |
if (c != null && evt.getClickCount() == 2 ) { |
405 |
if (c != null && evt.getClickCount() == 2 ) { |
342 |
CompletionItem selectedItem |
406 |
CompletionItem selectedItem |
343 |
= completionScrollPane.getSelectedCompletionItem(); |
407 |
= completionScrollPane.getSelectedCompletionItem(); |
Lines 382-388
Link Here
|
382 |
// Set the new data |
446 |
// Set the new data |
383 |
getPreferredSize(); |
447 |
getPreferredSize(); |
384 |
completionScrollPane.setData(data, title, selectedIndex); |
448 |
completionScrollPane.setData(data, title, selectedIndex); |
385 |
setAnchorOffset(anchorOffset); |
449 |
if (anchorOffset >= 0) |
|
|
450 |
setAnchorOffset(anchorOffset); |
451 |
if (location != null) |
452 |
setLocation(location); |
386 |
|
453 |
|
387 |
Dimension prefSize = getPreferredSize(); |
454 |
Dimension prefSize = getPreferredSize(); |
388 |
|
455 |
|
Lines 412-417
Link Here
|
412 |
return isVisible() ? completionScrollPane.getSelectedIndex() : -1; |
479 |
return isVisible() ? completionScrollPane.getSelectedIndex() : -1; |
413 |
} |
480 |
} |
414 |
|
481 |
|
|
|
482 |
public Point getSelectedLocation() { |
483 |
return isVisible() ? completionScrollPane.getSelectedLocation() : null; |
484 |
} |
485 |
|
415 |
public void processKeyEvent(KeyEvent evt) { |
486 |
public void processKeyEvent(KeyEvent evt) { |
416 |
if (isVisible()) { |
487 |
if (isVisible()) { |
417 |
Object actionMapKey = completionScrollPane.getInputMap().get( |
488 |
Object actionMapKey = completionScrollPane.getInputMap().get( |
Lines 431-437
Link Here
|
431 |
protected int getAnchorHorizontalShift() { |
502 |
protected int getAnchorHorizontalShift() { |
432 |
return COMPLETION_ANCHOR_HORIZONTAL_SHIFT; |
503 |
return COMPLETION_ANCHOR_HORIZONTAL_SHIFT; |
433 |
} |
504 |
} |
434 |
|
|
|
435 |
} |
505 |
} |
436 |
|
506 |
|
437 |
private static final class DocPopup extends CompletionLayoutPopup { |
507 |
private static final class DocPopup extends CompletionLayoutPopup { |
Lines 484-490
Link Here
|
484 |
protected int getAnchorHorizontalShift() { |
554 |
protected int getAnchorHorizontalShift() { |
485 |
return COMPLETION_ANCHOR_HORIZONTAL_SHIFT; |
555 |
return COMPLETION_ANCHOR_HORIZONTAL_SHIFT; |
486 |
} |
556 |
} |
487 |
|
|
|
488 |
} |
557 |
} |
489 |
|
558 |
|
490 |
private static final class TipPopup extends CompletionLayoutPopup { |
559 |
private static final class TipPopup extends CompletionLayoutPopup { |
Lines 514-521
Link Here
|
514 |
CompletionImpl.get().hideToolTip(); |
583 |
CompletionImpl.get().hideToolTip(); |
515 |
} |
584 |
} |
516 |
} |
585 |
} |
517 |
} |
586 |
} |
518 |
|
587 |
} |
519 |
} |
|
|
520 |
|
521 |
} |
588 |
} |