You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
210 lines
7.6 KiB
210 lines
7.6 KiB
/* |
|
* Copyright 2000-2014 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.bulenkov.darcula.ui; |
|
|
|
import com.bulenkov.darcula.DarculaUIUtil; |
|
import com.bulenkov.iconloader.util.GraphicsConfig; |
|
import com.bulenkov.iconloader.util.Gray; |
|
import com.bulenkov.iconloader.IconLoader; |
|
|
|
import javax.swing.*; |
|
import javax.swing.border.Border; |
|
import javax.swing.plaf.ComponentUI; |
|
import javax.swing.plaf.basic.BasicTextFieldUI; |
|
import javax.swing.text.JTextComponent; |
|
import java.awt.*; |
|
import java.awt.event.*; |
|
|
|
/** |
|
* @author Konstantin Bulenkov |
|
*/ |
|
public class DarculaTextFieldUI extends BasicTextFieldUI { |
|
private static final Icon SEARCH_ICON = IconLoader.findIcon("/com/intellij/ide/ui/laf/darcula/icons/search.png", DarculaTextFieldUI.class, true); |
|
private static final Icon SEARCH_WITH_HISTORY_ICON = IconLoader.findIcon("/com/intellij/ide/ui/laf/darcula/icons/searchWithHistory.png", DarculaTextFieldUI.class, true); |
|
private static final Icon CLEAR_ICON = IconLoader.findIcon("/com/intellij/ide/ui/laf/darcula/icons/clear.png", DarculaTextFieldUI.class, true); |
|
|
|
private enum SearchAction {POPUP, CLEAR} |
|
|
|
private final JTextField myTextField; |
|
protected JLabel myClearIcon; |
|
protected JLabel myRecentIcon; |
|
|
|
public DarculaTextFieldUI(JTextField textField) { |
|
myTextField = textField; |
|
} |
|
|
|
@SuppressWarnings("MethodOverridesStaticMethodOfSuperclass") |
|
public static ComponentUI createUI(final JComponent c) { |
|
final DarculaTextFieldUI ui = new DarculaTextFieldUI((JTextField)c); |
|
c.addFocusListener(new FocusAdapter() { |
|
@Override |
|
public void focusGained(FocusEvent e) { |
|
c.repaint(); |
|
} |
|
|
|
@Override |
|
public void focusLost(FocusEvent e) { |
|
c.repaint(); |
|
} |
|
}); |
|
c.addMouseMotionListener(new MouseMotionAdapter() { |
|
@Override |
|
public void mouseMoved(MouseEvent e) { |
|
if (ui.getComponent() != null && isSearchField(c)) { |
|
if (ui.getActionUnder(e) != null) { |
|
c.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); |
|
} else { |
|
c.setCursor(Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR)); |
|
} |
|
} |
|
} |
|
}); |
|
c.addMouseListener(new MouseAdapter() { |
|
@Override |
|
public void mouseClicked(MouseEvent e) { |
|
if (isSearchField(c)) { |
|
final SearchAction action = ui.getActionUnder(e); |
|
if (action != null) { |
|
switch (action) { |
|
case POPUP: |
|
ui.showSearchPopup(); |
|
break; |
|
case CLEAR: |
|
((JTextField)c).setText(""); |
|
break; |
|
} |
|
e.consume(); |
|
} |
|
} |
|
} |
|
}); |
|
return ui; |
|
} |
|
|
|
protected void showSearchPopup() { |
|
final Object value = getComponent().getClientProperty("JTextField.Search.FindPopup"); |
|
if (value instanceof JPopupMenu) { |
|
final JPopupMenu popup = (JPopupMenu)value; |
|
popup.show(getComponent(), getSearchIconCoord().x, getComponent().getHeight()); |
|
} |
|
} |
|
|
|
private SearchAction getActionUnder(MouseEvent e) { |
|
final Point cPoint = getClearIconCoord(); |
|
final Point sPoint = getSearchIconCoord(); |
|
cPoint.x+=8; |
|
cPoint.y+=8; |
|
sPoint.x+=8; |
|
sPoint.y+=8; |
|
final Point ePoint = e.getPoint(); |
|
return cPoint.distance(ePoint) <= 8 ? SearchAction.CLEAR : sPoint.distance(ePoint) <= 8 ? SearchAction.POPUP : null; |
|
} |
|
|
|
protected Rectangle getDrawingRect() { |
|
final JTextComponent c = myTextField; |
|
final Insets i = c.getInsets(); |
|
final int x = i.right - 4 - 16; |
|
final int y = i.top - 3; |
|
final int w = c.getWidth() - i.left - i.right + 16*2 +7*2 - 5; |
|
int h = c.getBounds().height - i.top - i.bottom + 4*2 - 3; |
|
if (h%2==1) h++; |
|
return new Rectangle(x, y, w, h); |
|
} |
|
|
|
protected Point getSearchIconCoord() { |
|
final Rectangle r = getDrawingRect(); |
|
return new Point(r.x + 3, r.y + (r.height - 16) / 2 + 1); |
|
} |
|
|
|
protected Point getClearIconCoord() { |
|
final Rectangle r = getDrawingRect(); |
|
return new Point(r.x + r.width - 16 - 1, r.y + (r.height - 16) / 2); |
|
} |
|
|
|
@Override |
|
protected void paintBackground(Graphics graphics) { |
|
Graphics2D g = (Graphics2D)graphics; |
|
final JTextComponent c = getComponent(); |
|
final Container parent = c.getParent(); |
|
final Rectangle r = getDrawingRect(); |
|
if (c.isOpaque() && parent != null) { |
|
g.setColor(parent.getBackground()); |
|
g.fillRect(0, 0, c.getWidth(), c.getHeight()); |
|
} |
|
final GraphicsConfig config = new GraphicsConfig(g); |
|
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); |
|
g.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_NORMALIZE); |
|
|
|
final Border border = c.getBorder(); |
|
if (isSearchField(c)) { |
|
g.setColor(c.getBackground()); |
|
|
|
int radius = r.height-1; |
|
g.fillRoundRect(r.x, r.y, r.width, r.height-1, radius, radius); |
|
g.setColor(c.isEnabled() ? Gray._100 : new Color(0x535353)); |
|
if (c.getClientProperty("JTextField.Search.noBorderRing") != Boolean.TRUE) { |
|
if (c.hasFocus()) { |
|
DarculaUIUtil.paintSearchFocusRing(g, r); |
|
} else { |
|
g.drawRoundRect(r.x, r.y, r.width, r.height-1, radius, radius); |
|
} |
|
} |
|
Point p = getSearchIconCoord(); |
|
Icon searchIcon = getComponent().getClientProperty("JTextField.Search.FindPopup") instanceof JPopupMenu ? UIManager.getIcon("TextField.darcula.searchWithHistory.icon") : UIManager.getIcon("TextField.darcula.search.icon"); |
|
if (searchIcon == null) { |
|
searchIcon = IconLoader.findIcon("/com/intellij/ide/ui/laf/icons/search.png", DarculaTextFieldUI.class, true); |
|
} |
|
searchIcon.paintIcon(null, g, p.x, p.y); |
|
if (getComponent().hasFocus() && getComponent().getText().length() > 0) { |
|
p = getClearIconCoord(); |
|
Icon clearIcon = UIManager.getIcon("TextField.darcula.clear.icon"); |
|
if (clearIcon == null) { |
|
clearIcon = IconLoader.findIcon("/com/intellij/ide/ui/laf/icons/clear.png", DarculaTextFieldUI.class, true); |
|
} |
|
clearIcon.paintIcon(null, g, p.x, p.y); |
|
} |
|
} else if (border instanceof DarculaTextBorder) { |
|
if (c.isEnabled() && c.isEditable()) { |
|
g.setColor(c.getBackground()); |
|
} |
|
final int width = c.getWidth(); |
|
final int height = c.getHeight(); |
|
final Insets i = border.getBorderInsets(c); |
|
if (c.hasFocus()) { |
|
g.fillRoundRect(i.left - 5, i.top - 2, width - i.right - i.left + 10, height - i.top - i.bottom + 6, 5, 5); |
|
} else { |
|
g.fillRect(i.left - 5, i.top - 2, width - i.right - i.left + 12, height - i.top - i.bottom + 6); |
|
} |
|
} else { |
|
super.paintBackground(g); |
|
} |
|
config.restore(); |
|
} |
|
|
|
@Override |
|
protected void paintSafely(Graphics g) { |
|
paintBackground(g); |
|
super.paintSafely(g); |
|
} |
|
|
|
public static boolean isSearchField(Component c) { |
|
return c instanceof JTextField && "search".equals(((JTextField)c).getClientProperty("JTextField.variant")); |
|
} |
|
|
|
public static boolean isSearchFieldWithHistoryPopup(Component c) { |
|
return isSearchField(c) && ((JTextField)c).getClientProperty("JTextField.Search.FindPopup") instanceof JPopupMenu; |
|
} |
|
}
|
|
|