private JComponent createLogo() { NonOpaquePanel panel = new NonOpaquePanel(new BorderLayout()); ApplicationInfoEx app = ApplicationInfoEx.getInstanceEx(); JLabel logo = new JLabel(IconLoader.getIcon(app.getWelcomeScreenLogoUrl())); logo.setBorder(JBUI.Borders.empty(30, 0, 10, 0)); logo.setHorizontalAlignment(SwingConstants.CENTER); panel.add(logo, BorderLayout.NORTH); JLabel appName = new JLabel(ApplicationNamesInfo.getInstance().getFullProductName()); Font font = getProductFont(); appName.setForeground(JBColor.foreground()); appName.setFont(font.deriveFont(JBUI.scale(36f)).deriveFont(Font.PLAIN)); appName.setHorizontalAlignment(SwingConstants.CENTER); String appVersion = "Version " + app.getFullVersion(); if (app.isEAP() && app.getBuild().getBuildNumber() < Integer.MAX_VALUE) { appVersion += " (" + app.getBuild().asString() + ")"; } JLabel version = new JLabel(appVersion); version.setFont(getProductFont().deriveFont(JBUI.scale(16f))); version.setHorizontalAlignment(SwingConstants.CENTER); version.setForeground(Gray._128); panel.add(appName); panel.add(version, BorderLayout.SOUTH); panel.setBorder(JBUI.Borders.emptyBottom(20)); return panel; }
/** Sets current LAF. The method doesn't update component hierarchy. */ @Override public void setCurrentLookAndFeel(UIManager.LookAndFeelInfo lookAndFeelInfo) { if (findLaf(lookAndFeelInfo.getClassName()) == null) { LOG.error("unknown LookAndFeel : " + lookAndFeelInfo); return; } // Set L&F if (IdeaLookAndFeelInfo.CLASS_NAME.equals( lookAndFeelInfo.getClassName())) { // that is IDEA default LAF IdeaLaf laf = new IdeaLaf(); MetalLookAndFeel.setCurrentTheme(new IdeaBlueMetalTheme()); try { UIManager.setLookAndFeel(laf); } catch (Exception e) { Messages.showMessageDialog( IdeBundle.message( "error.cannot.set.look.and.feel", lookAndFeelInfo.getName(), e.getMessage()), CommonBundle.getErrorTitle(), Messages.getErrorIcon()); return; } } else if (DarculaLookAndFeelInfo.CLASS_NAME.equals(lookAndFeelInfo.getClassName())) { DarculaLaf laf = new DarculaLaf(); try { UIManager.setLookAndFeel(laf); JBColor.setDark(true); IconLoader.setUseDarkIcons(true); } catch (Exception e) { Messages.showMessageDialog( IdeBundle.message( "error.cannot.set.look.and.feel", lookAndFeelInfo.getName(), e.getMessage()), CommonBundle.getErrorTitle(), Messages.getErrorIcon()); return; } } else { // non default LAF try { LookAndFeel laf = ((LookAndFeel) Class.forName(lookAndFeelInfo.getClassName()).newInstance()); if (laf instanceof MetalLookAndFeel) { MetalLookAndFeel.setCurrentTheme(new DefaultMetalTheme()); } UIManager.setLookAndFeel(laf); } catch (Exception e) { Messages.showMessageDialog( IdeBundle.message( "error.cannot.set.look.and.feel", lookAndFeelInfo.getName(), e.getMessage()), CommonBundle.getErrorTitle(), Messages.getErrorIcon()); return; } } myCurrentLaf = ObjectUtils.chooseNotNull(findLaf(lookAndFeelInfo.getClassName()), lookAndFeelInfo); checkLookAndFeel(lookAndFeelInfo, false); }
private static Color getTypeTextColor( LookupElement item, Color foreground, LookupElementPresentation presentation, boolean selected, boolean nonFocusedSelection) { if (nonFocusedSelection) { return foreground; } return presentation.isTypeGrayed() ? getGrayedForeground(selected) : item instanceof EmptyLookupItem ? JBColor.foreground() : foreground; }
public JavaFxHtmlPanel() { // System.setProperty("prism.lcdtext", "false"); // System.setProperty("prism.text", "t2k"); myPanelWrapper = new JPanel(new BorderLayout()); myPanelWrapper.setBackground(JBColor.background()); ApplicationManager.getApplication() .invokeLater( () -> PlatformImpl.startup( () -> { myWebView = new WebView(); updateFontSmoothingType( myWebView, MarkdownApplicationSettings.getInstance() .getMarkdownPreviewSettings() .isUseGrayscaleRendering()); myWebView.setContextMenuEnabled(false); final WebEngine engine = myWebView.getEngine(); engine.getLoadWorker().stateProperty().addListener(myBridgeSettingListener); engine .getLoadWorker() .stateProperty() .addListener(myScrollPreservingListener); final Scene scene = new Scene(myWebView); ApplicationManager.getApplication() .invokeLater( () -> { myPanel = new JFXPanelWrapper(); myPanel.setScene(scene); setHtml(""); for (Runnable action : myInitActions) { Platform.runLater(action); } myInitActions.clear(); myPanelWrapper.add(myPanel, BorderLayout.CENTER); myPanelWrapper.repaint(); }); })); subscribeForGrayscaleSetting(); }
private void determineColors() { switch (getWindowDecorationStyle()) { case JRootPane.FRAME: myActiveBackground = UIManager.getColor("activeCaption"); myActiveForeground = UIManager.getColor("activeCaptionText"); myActiveShadow = UIManager.getColor("activeCaptionBorder"); break; case JRootPane.ERROR_DIALOG: myActiveBackground = new Color( 43, 43, 43); // UIManager.getColor("OptionPane.errorDialog.titlePane.background"); myActiveForeground = UIManager.getColor("OptionPane.errorDialog.titlePane.foreground"); myActiveShadow = UIManager.getColor("OptionPane.errorDialog.titlePane.shadow"); break; case JRootPane.QUESTION_DIALOG: case JRootPane.COLOR_CHOOSER_DIALOG: case JRootPane.FILE_CHOOSER_DIALOG: myActiveBackground = new Color( 43, 43, 43); // UIManager.getColor("OptionPane.questionDialog.titlePane.background"); myActiveForeground = UIManager.getColor("OptionPane.questionDialog.titlePane.foreground"); myActiveShadow = UIManager.getColor("OptionPane.questionDialog.titlePane.shadow"); break; case JRootPane.WARNING_DIALOG: myActiveBackground = new Color( 43, 43, 43); // UIManager.getColor("OptionPane.warningDialog.titlePane.background"); myActiveForeground = UIManager.getColor("OptionPane.warningDialog.titlePane.foreground"); myActiveShadow = UIManager.getColor("OptionPane.warningDialog.titlePane.shadow"); break; case JRootPane.PLAIN_DIALOG: case JRootPane.INFORMATION_DIALOG: default: myActiveBackground = new Color(43, 43, 43); // UIManager.getColor("activeCaption"); myActiveForeground = UIManager.getColor("activeCaptionText"); myActiveShadow = UIManager.getColor("activeCaptionBorder"); break; } myActiveBackground = new Color(43, 43, 43); // UIManager.getColor("activeCaption"); myActiveForeground = JBColor.foreground(); // UIManager.getColor("activeCaptionText"); myActiveShadow = UIManager.getColor("activeCaptionBorder"); }
private String setup( @NotNull String text, @NotNull Map<TextRange, ParameterInfoUIContextEx.Flag> flagsMap, @NotNull Color background) { myLabel.setBackground(background); setBackground(background); myLabel.setForeground(JBColor.foreground()); if (flagsMap.isEmpty()) { myLabel.setText(XmlStringUtil.wrapInHtml(text)); } else { String labelText = buildLabelText(text, flagsMap); myLabel.setText(labelText); } // IDEA-95904 Darcula parameter info pop-up colors hard to read if (UIUtil.isUnderDarcula()) { myLabel.setText(myLabel.getText().replace("<b>", "<b color=ffC800>")); } return myLabel.getText(); }
public void activate() { try { UIManager.setLookAndFeel(new MTLaf(this)); JBColor.setDark(dark); IconLoader.setUseDarkIcons(dark); PropertiesComponent.getInstance().setValue(getSettingsPrefix() + ".theme", name()); } catch (UnsupportedLookAndFeelException e) { e.printStackTrace(); } String currentScheme = EditorColorsManager.getInstance().getGlobalScheme().getName(); String makeActiveScheme = !EDITOR_COLORS_SCHEMES.contains(currentScheme) ? currentScheme : editorColorsScheme; EditorColorsScheme scheme = EditorColorsManager.getInstance().getScheme(makeActiveScheme); if (scheme != null) { EditorColorsManager.getInstance().setGlobalScheme(scheme); } UISettings.getInstance().fireUISettingsChanged(); ActionToolbarImpl.updateAllToolbarsImmediately(); }
public CustomizePluginsStepPanel() { myCardLayout = new JBCardLayout(); setLayout(myCardLayout); JPanel gridPanel = new JPanel(new GridLayout(0, COLS)); myCustomizePanel = new IdSetPanel(); JBScrollPane scrollPane = new JBScrollPane( gridPanel, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); scrollPane.getVerticalScrollBar().setUnitIncrement(10); add(scrollPane, MAIN); add(myCustomizePanel, CUSTOMIZE); // PluginManager.loadDisabledPlugins(new File(PathManager.getConfigPath()).getPath(), // myDisabledPluginIds); // for (IdeaPluginDescriptor pluginDescriptor : myAllPlugins) { // if (pluginDescriptor.getPluginId().getIdString().equals("com.intellij")) { //// skip 'IDEA CORE' plugin // continue; // } // //PluginManager.initClassLoader(PluginGroups.class.getClassLoader(), // (IdeaPluginDescriptorImpl)pluginDescriptor); // } Map<String, List<String>> groups = PluginGroups.getInstance().getTree(); for (Map.Entry<String, List<String>> entry : groups.entrySet()) { final String group = entry.getKey(); if (PluginGroups.CORE.equals(group)) continue; JPanel groupPanel = new JPanel(new GridBagLayout()); GridBagConstraints gbc = new GridBagConstraints(); gbc.insets = new Insets(0, 0, 10, 0); gbc.fill = GridBagConstraints.BOTH; gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.weightx = 1; JLabel titleLabel = new JLabel( "<html><body><h2 style=\"text-align:left;\">" + group + "</h2></body></html>") { @Override public boolean isEnabled() { return isGroupEnabled(group); } }; groupPanel.add(titleLabel, gbc); JLabel descriptionLabel = new JLabel(PluginGroups.getInstance().getDescription(group)) { @Override public Dimension getPreferredSize() { Dimension size = super.getPreferredSize(); size.width = Math.min(size.width, 200); return size; } @Override public boolean isEnabled() { return isGroupEnabled(group); } @Override public Color getForeground() { return ColorUtil.withAlpha(UIManager.getColor("Label.foreground"), .75); } }; groupPanel.add(descriptionLabel, gbc); gbc.weighty = 1; groupPanel.add(Box.createVerticalGlue(), gbc); gbc.weighty = 0; if (PluginGroups.getInstance().getSets(group).size() == 1) { groupPanel.add( createLink(SWITCH_COMMAND + ":" + group, getGroupSwitchTextProvider(group)), gbc); } else { JPanel buttonsPanel = new JPanel(new GridLayout(1, 2, 10, 5)); LinkLabel customizeButton = createLink(CUSTOMIZE_COMMAND + ":" + group, CUSTOMIZE_TEXT_PROVIDER); buttonsPanel.add(customizeButton); LinkLabel disableAllButton = createLink(SWITCH_COMMAND + ":" + group, getGroupSwitchTextProvider(group)); buttonsPanel.add(disableAllButton); groupPanel.add(buttonsPanel, gbc); } gridPanel.add(groupPanel); } int cursor = 0; Component[] components = gridPanel.getComponents(); int rowCount = components.length / COLS; for (Component component : components) { ((JComponent) component) .setBorder( new CompoundBorder( new CustomLineBorder( ColorUtil.withAlpha(JBColor.foreground(), .2), 0, 0, cursor / 3 < rowCount - 1 ? 1 : 0, cursor % COLS != COLS - 1 ? 1 : 0) { @Override protected Color getColor() { return ColorUtil.withAlpha(JBColor.foreground(), .2); } }, BorderFactory.createEmptyBorder(GAP, GAP, GAP, GAP))); cursor++; } }
/** @author peter */ public class LookupElementPresentation { private Icon myIcon; private Icon myTypeIcon; private String myItemText; private String myTypeText; private boolean myStrikeout; private Color myItemTextForeground = JBColor.foreground(); private boolean myItemTextBold; private boolean myItemTextUnderlined; private boolean myTypeGrayed; @Nullable private List<TextFragment> myTail; public void setIcon(@Nullable Icon icon) { myIcon = icon; } public void setItemText(@Nullable String text) { myItemText = text; } public void setStrikeout(boolean strikeout) { myStrikeout = strikeout; } public void setItemTextBold(boolean bold) { myItemTextBold = bold; } public void setTailText(@Nullable String text) { setTailText(text, false); } public void clearTail() { myTail = null; } public void appendTailText(@NotNull String text, boolean grayed) { appendTailText(new TextFragment(text, grayed, null)); } private void appendTailText(@NotNull TextFragment fragment) { if (myTail == null) { myTail = new SmartList<TextFragment>(); } myTail.add(fragment); } public void setTailText(@Nullable String text, boolean grayed) { clearTail(); if (text != null) { appendTailText(new TextFragment(text, grayed, null)); } } public void setTailText(@Nullable String text, @Nullable Color foreground) { clearTail(); if (text != null) { appendTailText(new TextFragment(text, false, foreground)); } } public void setTypeText(@Nullable String text) { setTypeText(text, null); } public void setTypeText(@Nullable String text, @Nullable Icon icon) { myTypeText = text; myTypeIcon = icon; } /** * Is equivalent to instanceof {@link * com.intellij.codeInsight.lookup.RealLookupElementPresentation} check. * * @return whether the presentation is requested to actually render lookup element on screen, or * just to estimate its width. In the second, 'non-real' case, some heavy operations (e.g. * getIcon()) can be omitted (only icon width is important) */ public boolean isReal() { return false; } @Nullable public Icon getIcon() { return myIcon; } @Nullable public Icon getTypeIcon() { return myTypeIcon; } @Nullable public String getItemText() { return myItemText; } @NotNull public List<TextFragment> getTailFragments() { return myTail == null ? Collections.<TextFragment>emptyList() : Collections.unmodifiableList(myTail); } @Nullable public String getTailText() { if (myTail == null) return null; return StringUtil.join(myTail, fragment -> fragment.text, ""); } @Nullable public String getTypeText() { return myTypeText; } public boolean isStrikeout() { return myStrikeout; } @Deprecated public boolean isTailGrayed() { return myTail != null && myTail.get(0).grayed; } @Nullable @Deprecated public Color getTailForeground() { return myTail != null ? myTail.get(0).fgColor : null; } public boolean isItemTextBold() { return myItemTextBold; } public boolean isItemTextUnderlined() { return myItemTextUnderlined; } public void setItemTextUnderlined(boolean itemTextUnderlined) { myItemTextUnderlined = itemTextUnderlined; } @NotNull public Color getItemTextForeground() { return myItemTextForeground; } public void setItemTextForeground(@NotNull Color itemTextForeground) { myItemTextForeground = itemTextForeground; } public void copyFrom(@NotNull LookupElementPresentation presentation) { myIcon = presentation.myIcon; myTypeIcon = presentation.myTypeIcon; myItemText = presentation.myItemText; List<TextFragment> thatTail = presentation.myTail; myTail = thatTail == null ? null : new SmartList<TextFragment>(thatTail); myTypeText = presentation.myTypeText; myStrikeout = presentation.myStrikeout; myItemTextBold = presentation.myItemTextBold; myTypeGrayed = presentation.myTypeGrayed; myItemTextUnderlined = presentation.myItemTextUnderlined; myItemTextForeground = presentation.myItemTextForeground; } public boolean isTypeGrayed() { return myTypeGrayed; } public void setTypeGrayed(boolean typeGrayed) { myTypeGrayed = typeGrayed; } public static LookupElementPresentation renderElement(LookupElement element) { LookupElementPresentation presentation = new LookupElementPresentation(); element.renderElement(presentation); return presentation; } @Override public String toString() { return "LookupElementPresentation{" + ", itemText='" + myItemText + '\'' + ", tail=" + myTail + ", typeText='" + myTypeText + '\'' + '}'; } public static class TextFragment { public final String text; private final boolean grayed; @Nullable private final Color fgColor; public TextFragment(String text, boolean grayed, @Nullable Color fgColor) { this.text = text; this.grayed = grayed; this.fgColor = fgColor; } @Override public String toString() { return "TextFragment{" + "text='" + text + '\'' + ", grayed=" + grayed + ", fgColor=" + fgColor + '}'; } public boolean isGrayed() { return grayed; } @Nullable public Color getForegroundColor() { return fgColor; } } }
/** * @author peter * @author Konstantin Bulenkov */ public class LookupCellRenderer implements ListCellRenderer { private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.lookup.impl.LookupCellRenderer"); // TODO[kb]: move all these awesome constants to Editor's Fonts & Colors settings private static final int AFTER_TAIL = 10; private static final int AFTER_TYPE = 6; private Icon myEmptyIcon = EmptyIcon.create(5); private final Font myNormalFont; private final Font myBoldFont; private final FontMetrics myNormalMetrics; private final FontMetrics myBoldMetrics; public static final Color BACKGROUND_COLOR = new JBColor(new Color(235, 244, 254), JBColor.background()); private static final Color FOREGROUND_COLOR = JBColor.foreground(); private static final Color GRAYED_FOREGROUND_COLOR = new JBColor(Gray._160, Gray._110); private static final Color SELECTED_BACKGROUND_COLOR = new Color(0, 82, 164); private static final Color SELECTED_NON_FOCUSED_BACKGROUND_COLOR = new JBColor(new Color(110, 142, 162), new Color(85, 88, 90)); private static final Color SELECTED_FOREGROUND_COLOR = new JBColor(JBColor.WHITE, JBColor.foreground()); private static final Color SELECTED_GRAYED_FOREGROUND_COLOR = new JBColor(JBColor.WHITE, JBColor.foreground()); static final Color PREFIX_FOREGROUND_COLOR = new JBColor(new Color(176, 0, 176), new Color(209, 122, 214)); private static final Color SELECTED_PREFIX_FOREGROUND_COLOR = new JBColor(new Color(249, 236, 204), new Color(209, 122, 214)); private final LookupImpl myLookup; private final SimpleColoredComponent myNameComponent; private final SimpleColoredComponent myTailComponent; private final SimpleColoredComponent myTypeLabel; private final LookupPanel myPanel; private final Map<Integer, Boolean> mySelected = new HashMap<Integer, Boolean>(); private static final String ELLIPSIS = "\u2026"; private int myMaxWidth = -1; public LookupCellRenderer(LookupImpl lookup) { EditorColorsScheme scheme = lookup.getEditor().getColorsScheme(); myNormalFont = scheme.getFont(EditorFontType.PLAIN); myBoldFont = scheme.getFont(EditorFontType.BOLD); myLookup = lookup; myNameComponent = new MySimpleColoredComponent(); myNameComponent.setIpad(new Insets(0, 0, 0, 0)); myTailComponent = new MySimpleColoredComponent(); myTailComponent.setIpad(new Insets(0, 0, 0, 0)); myTypeLabel = new MySimpleColoredComponent(); myTypeLabel.setIpad(new Insets(0, 0, 0, 0)); myPanel = new LookupPanel(); myPanel.add(myNameComponent, BorderLayout.WEST); myPanel.add(myTailComponent, BorderLayout.CENTER); myTailComponent.setBorder(new EmptyBorder(0, 0, 0, AFTER_TAIL)); myPanel.add(myTypeLabel, BorderLayout.EAST); myTypeLabel.setBorder(new EmptyBorder(0, 0, 0, AFTER_TYPE)); myNormalMetrics = myLookup.getEditor().getComponent().getFontMetrics(myNormalFont); myBoldMetrics = myLookup.getEditor().getComponent().getFontMetrics(myBoldFont); } private boolean myIsSelected = false; @Override public Component getListCellRendererComponent( final JList list, Object value, int index, boolean isSelected, boolean hasFocus) { boolean nonFocusedSelection = isSelected && myLookup.getFocusDegree() == LookupImpl.FocusDegree.SEMI_FOCUSED; if (!myLookup.isFocused()) { isSelected = false; } myIsSelected = isSelected; final LookupElement item = (LookupElement) value; final Color foreground = getForegroundColor(isSelected); final Color background = nonFocusedSelection ? SELECTED_NON_FOCUSED_BACKGROUND_COLOR : isSelected ? SELECTED_BACKGROUND_COLOR : BACKGROUND_COLOR; int allowedWidth = list.getWidth() - AFTER_TAIL - AFTER_TYPE - getIconIndent(); FontMetrics normalMetrics = getRealFontMetrics(item, false); FontMetrics boldMetrics = getRealFontMetrics(item, true); final LookupElementPresentation presentation = new RealLookupElementPresentation( isSelected ? getMaxWidth() : allowedWidth, normalMetrics, boldMetrics, myLookup); AccessToken token = ReadAction.start(); try { if (item.isValid()) { try { item.renderElement(presentation); } catch (Exception e) { LOG.error(e); } catch (Error e) { LOG.error(e); } } else { presentation.setItemTextForeground(JBColor.RED); presentation.setItemText("Invalid"); } } finally { token.finish(); } myNameComponent.clear(); myNameComponent.setIcon(augmentIcon(presentation.getIcon(), myEmptyIcon)); myNameComponent.setBackground(background); allowedWidth -= setItemTextLabel( item, new JBColor( isSelected ? SELECTED_FOREGROUND_COLOR : presentation.getItemTextForeground(), foreground), isSelected, presentation, allowedWidth); Font customFont = myLookup.getCustomFont(item, false); myTailComponent.setFont(customFont != null ? customFont : myNormalFont); myTypeLabel.setFont(customFont != null ? customFont : myNormalFont); myTypeLabel.clear(); if (allowedWidth > 0) { allowedWidth -= setTypeTextLabel( item, background, foreground, presentation, isSelected ? getMaxWidth() : allowedWidth, isSelected, nonFocusedSelection, normalMetrics); } myTailComponent.clear(); myTailComponent.setBackground(background); if (isSelected || allowedWidth >= 0) { setTailTextLabel( isSelected, presentation, foreground, isSelected ? getMaxWidth() : allowedWidth, nonFocusedSelection, normalMetrics); } if (mySelected.containsKey(index)) { if (!isSelected && mySelected.get(index)) { myPanel.setUpdateExtender(true); } } mySelected.put(index, isSelected); final double w = myNameComponent.getPreferredSize().getWidth() + myTailComponent.getPreferredSize().getWidth() + myTypeLabel.getPreferredSize().getWidth(); boolean useBoxLayout = isSelected && w > list.getWidth() && ((JBList) list).getExpandableItemsHandler().isEnabled(); if (useBoxLayout != myPanel.getLayout() instanceof BoxLayout) { myPanel.removeAll(); if (useBoxLayout) { myPanel.setLayout(new BoxLayout(myPanel, BoxLayout.X_AXIS)); myPanel.add(myNameComponent); myPanel.add(myTailComponent); myPanel.add(myTypeLabel); } else { myPanel.setLayout(new BorderLayout()); myPanel.add(myNameComponent, BorderLayout.WEST); myPanel.add(myTailComponent, BorderLayout.CENTER); myPanel.add(myTypeLabel, BorderLayout.EAST); } } return myPanel; } private static Color getForegroundColor(boolean isSelected) { return isSelected ? SELECTED_FOREGROUND_COLOR : FOREGROUND_COLOR; } private int getMaxWidth() { if (myMaxWidth < 0) { final Point p = myLookup.getComponent().getLocationOnScreen(); final Rectangle rectangle = ScreenUtil.getScreenRectangle(p); myMaxWidth = rectangle.x + rectangle.width - p.x - 111; } return myMaxWidth; } private void setTailTextLabel( boolean isSelected, LookupElementPresentation presentation, Color foreground, int allowedWidth, boolean nonFocusedSelection, FontMetrics fontMetrics) { int style = getStyle(false, presentation.isStrikeout(), false); for (LookupElementPresentation.TextFragment fragment : presentation.getTailFragments()) { if (allowedWidth < 0) { return; } String trimmed = trimLabelText(fragment.text, allowedWidth, fontMetrics); myTailComponent.append( trimmed, new SimpleTextAttributes( style, getTailTextColor(isSelected, fragment, foreground, nonFocusedSelection))); allowedWidth -= RealLookupElementPresentation.getStringWidth(trimmed, fontMetrics); } } private String trimLabelText(@Nullable String text, int maxWidth, FontMetrics metrics) { if (text == null || StringUtil.isEmpty(text)) { return ""; } final int strWidth = RealLookupElementPresentation.getStringWidth(text, metrics); if (strWidth <= maxWidth || myIsSelected) { return text; } if (RealLookupElementPresentation.getStringWidth(ELLIPSIS, metrics) > maxWidth) { return ""; } int i = 0; int j = text.length(); while (i + 1 < j) { int mid = (i + j) / 2; final String candidate = text.substring(0, mid) + ELLIPSIS; final int width = RealLookupElementPresentation.getStringWidth(candidate, metrics); if (width <= maxWidth) { i = mid; } else { j = mid; } } return text.substring(0, i) + ELLIPSIS; } private static Color getTypeTextColor( LookupElement item, Color foreground, LookupElementPresentation presentation, boolean selected, boolean nonFocusedSelection) { if (nonFocusedSelection) { return foreground; } return presentation.isTypeGrayed() ? getGrayedForeground(selected) : item instanceof EmptyLookupItem ? JBColor.foreground() : foreground; } private static Color getTailTextColor( boolean isSelected, LookupElementPresentation.TextFragment fragment, Color defaultForeground, boolean nonFocusedSelection) { if (nonFocusedSelection) { return defaultForeground; } if (fragment.isGrayed()) { return getGrayedForeground(isSelected); } if (!isSelected) { final Color tailForeground = fragment.getForegroundColor(); if (tailForeground != null) { return tailForeground; } } return defaultForeground; } public static Color getGrayedForeground(boolean isSelected) { return isSelected ? SELECTED_GRAYED_FOREGROUND_COLOR : GRAYED_FOREGROUND_COLOR; } private int setItemTextLabel( LookupElement item, final Color foreground, final boolean selected, LookupElementPresentation presentation, int allowedWidth) { boolean bold = presentation.isItemTextBold(); Font customItemFont = myLookup.getCustomFont(item, bold); myNameComponent.setFont( customItemFont != null ? customItemFont : bold ? myBoldFont : myNormalFont); int style = getStyle(bold, presentation.isStrikeout(), presentation.isItemTextUnderlined()); final FontMetrics metrics = getRealFontMetrics(item, bold); final String name = trimLabelText(presentation.getItemText(), allowedWidth, metrics); int used = RealLookupElementPresentation.getStringWidth(name, metrics); renderItemName(item, foreground, selected, style, name, myNameComponent); return used; } private FontMetrics getRealFontMetrics(LookupElement item, boolean bold) { Font customFont = myLookup.getCustomFont(item, bold); if (customFont != null) { return myLookup.getEditor().getComponent().getFontMetrics(customFont); } return bold ? myBoldMetrics : myNormalMetrics; } @SimpleTextAttributes.StyleAttributeConstant private static int getStyle(boolean bold, boolean strikeout, boolean underlined) { int style = bold ? SimpleTextAttributes.STYLE_BOLD : SimpleTextAttributes.STYLE_PLAIN; if (strikeout) { style |= SimpleTextAttributes.STYLE_STRIKEOUT; } if (underlined) { style |= SimpleTextAttributes.STYLE_UNDERLINE; } return style; } private void renderItemName( LookupElement item, Color foreground, boolean selected, @SimpleTextAttributes.StyleAttributeConstant int style, String name, final SimpleColoredComponent nameComponent) { final SimpleTextAttributes base = new SimpleTextAttributes(style, foreground); final String prefix = item instanceof EmptyLookupItem ? "" : myLookup.itemPattern(item); if (prefix.length() > 0) { Iterable<TextRange> ranges = getMatchingFragments(prefix, name); if (ranges != null) { SimpleTextAttributes highlighted = new SimpleTextAttributes( style, selected ? SELECTED_PREFIX_FOREGROUND_COLOR : PREFIX_FOREGROUND_COLOR); SpeedSearchUtil.appendColoredFragments(nameComponent, name, ranges, base, highlighted); return; } } nameComponent.append(name, base); } public static FList<TextRange> getMatchingFragments(String prefix, String name) { return new MinusculeMatcher("*" + prefix, NameUtil.MatchingCaseSensitivity.NONE) .matchingFragments(name); } private int setTypeTextLabel( LookupElement item, final Color background, Color foreground, final LookupElementPresentation presentation, int allowedWidth, boolean selected, boolean nonFocusedSelection, FontMetrics normalMetrics) { final String givenText = presentation.getTypeText(); final String labelText = trimLabelText( StringUtil.isEmpty(givenText) ? "" : " " + givenText, allowedWidth, normalMetrics); int used = RealLookupElementPresentation.getStringWidth(labelText, normalMetrics); final Icon icon = presentation.getTypeIcon(); if (icon != null) { myTypeLabel.setIcon(icon); used += icon.getIconWidth(); } Color sampleBackground = background; Object o = item.isValid() ? item.getObject() : null; //noinspection deprecation if (o instanceof LookupValueWithUIHint && StringUtil.isEmpty(labelText)) { //noinspection deprecation Color proposedBackground = ((LookupValueWithUIHint) o).getColorHint(); if (proposedBackground != null) { sampleBackground = proposedBackground; } myTypeLabel.append(" "); used += normalMetrics.stringWidth("WW"); } else { myTypeLabel.append(labelText); } myTypeLabel.setBackground(sampleBackground); myTypeLabel.setForeground( getTypeTextColor(item, foreground, presentation, selected, nonFocusedSelection)); return used; } public static Icon augmentIcon(@Nullable Icon icon, @NotNull Icon standard) { if (icon == null) { return standard; } if (icon.getIconHeight() < standard.getIconHeight() || icon.getIconWidth() < standard.getIconWidth()) { final LayeredIcon layeredIcon = new LayeredIcon(2); layeredIcon.setIcon(icon, 0, 0, (standard.getIconHeight() - icon.getIconHeight()) / 2); layeredIcon.setIcon(standard, 1); return layeredIcon; } return icon; } @Nullable Font getFontAbleToDisplay(LookupElementPresentation p) { String sampleString = p.getItemText() + p.getTailText() + p.getTypeText(); // assume a single font can display all lookup item chars Set<Font> fonts = ContainerUtil.newHashSet(); for (int i = 0; i < sampleString.length(); i++) { fonts.add( EditorUtil.fontForChar(sampleString.charAt(i), Font.PLAIN, myLookup.getEditor()) .getFont()); } eachFont: for (Font font : fonts) { if (font.equals(myNormalFont)) continue; for (int i = 0; i < sampleString.length(); i++) { if (!font.canDisplay(sampleString.charAt(i))) { continue eachFont; } } return font; } return null; } int updateMaximumWidth(final LookupElementPresentation p, LookupElement item) { final Icon icon = p.getIcon(); if (icon != null && (icon.getIconWidth() > myEmptyIcon.getIconWidth() || icon.getIconHeight() > myEmptyIcon.getIconHeight())) { myEmptyIcon = new EmptyIcon( Math.max(icon.getIconWidth(), myEmptyIcon.getIconWidth()), Math.max(icon.getIconHeight(), myEmptyIcon.getIconHeight())); } return RealLookupElementPresentation.calculateWidth( p, getRealFontMetrics(item, false), getRealFontMetrics(item, true)) + AFTER_TAIL + AFTER_TYPE; } public int getIconIndent() { return myNameComponent.getIconTextGap() + myEmptyIcon.getIconWidth(); } private static class MySimpleColoredComponent extends SimpleColoredComponent { private MySimpleColoredComponent() { setFocusBorderAroundIcon(true); } @Override protected void applyAdditionalHints(Graphics g) { GraphicsUtil.setupAntialiasing(g); } } private class LookupPanel extends JPanel { boolean myUpdateExtender; public LookupPanel() { super(new BorderLayout()); } public void setUpdateExtender(boolean updateExtender) { myUpdateExtender = updateExtender; } @Override public void paint(Graphics g) { if (!myLookup.isFocused() && myLookup.isCompletion()) { ((Graphics2D) g).setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.6f)); } super.paint(g); } } }