NPE fixed
[fedora-idea.git] / platform-api / src / com / intellij / ui / tabs / impl / TabLabel.java
blobbda0d3ad30f9a11c87ca0a2aa12054d9024edde0
1 package com.intellij.ui.tabs.impl;
3 import com.intellij.ide.DataManager;
4 import com.intellij.openapi.actionSystem.ActionGroup;
5 import com.intellij.openapi.actionSystem.ActionPlaces;
6 import com.intellij.openapi.actionSystem.DefaultActionGroup;
7 import com.intellij.openapi.util.Pass;
8 import com.intellij.ui.LayeredIcon;
9 import com.intellij.ui.SimpleColoredComponent;
10 import com.intellij.ui.SimpleColoredText;
11 import com.intellij.ui.components.panels.Wrapper;
12 import com.intellij.ui.tabs.TabInfo;
13 import com.intellij.ui.tabs.UiDecorator;
14 import com.intellij.util.ui.Centerizer;
16 import javax.swing.*;
17 import javax.swing.border.EmptyBorder;
18 import java.awt.*;
19 import java.awt.event.MouseAdapter;
20 import java.awt.event.MouseEvent;
22 public class TabLabel extends JPanel {
23 private SimpleColoredComponent myLabel = new SimpleColoredComponent();
24 private LayeredIcon myIcon;
25 private Icon myOverlayedIcon;
27 private TabInfo myInfo;
28 private ActionPanel myActionPanel;
29 private boolean myCentered;
31 private Wrapper myLabelPlaceholder = new Wrapper();
32 private JBTabsImpl myTabs;
34 public TabLabel(JBTabsImpl tabs, final TabInfo info) {
35 myTabs = tabs;
36 myInfo = info;
37 myLabel.setOpaque(false);
38 myLabel.setBorder(null);
39 myLabel.setIconTextGap(new JLabel().getIconTextGap());
40 myLabel.setIconOpaque(false);
41 myLabel.setIpad(new Insets(0, 0, 0, 0));
42 setOpaque(false);
43 setLayout(new BorderLayout());
46 myLabelPlaceholder.setOpaque(false);
47 add(myLabelPlaceholder, BorderLayout.CENTER);
49 setAligmentToCenter(true);
51 myIcon = new LayeredIcon(2);
52 myLabel.setIcon(myIcon);
54 addMouseListener(new MouseAdapter() {
55 public void mousePressed(final MouseEvent e) {
56 if (myTabs.isSelectionClick(e, false)) {
57 myTabs.select(info, true);
59 else {
60 handlePopup(e);
64 public void mouseClicked(final MouseEvent e) {
65 handlePopup(e);
68 public void mouseReleased(final MouseEvent e) {
69 handlePopup(e);
71 });
74 public void setAligmentToCenter(boolean toCenter) {
75 if (myCentered == toCenter && myLabel.getParent() != null) return;
77 myLabelPlaceholder.removeAll();
79 if (toCenter) {
80 final Centerizer center = new Centerizer(myLabel);
81 myLabelPlaceholder.setContent(center);
82 } else {
83 myLabelPlaceholder.setContent(myLabel);
86 myCentered = toCenter;
89 public void paint(final Graphics g) {
90 if (myTabs.getSelectedInfo() != myInfo) {
91 g.translate(0, 2);
92 } else {
93 g.translate(0, 1);
96 super.paint(g);
98 if (myTabs.getSelectedInfo() != myInfo) {
99 g.translate(0, -2);
100 } else {
101 g.translate(0, 1);
105 private void handlePopup(final MouseEvent e) {
106 if (e.getClickCount() != 1 || !e.isPopupTrigger()) return;
108 if (e.getX() < 0 || e.getX() >= e.getComponent().getWidth() || e.getY() < 0 || e.getY() >= e.getComponent().getHeight()) return;
110 String place = myTabs.getPopupPlace();
111 place = place != null ? place : ActionPlaces.UNKNOWN;
112 myTabs.myPopupInfo = myInfo;
114 final DefaultActionGroup toShow = new DefaultActionGroup();
115 if (myTabs.getPopupGroup() != null) {
116 toShow.addAll(myTabs.getPopupGroup());
117 toShow.addSeparator();
120 Object tabs =
121 DataManager.getInstance().getDataContext(e.getComponent(), e.getX(), e.getY()).getData(JBTabsImpl.NAVIGATION_ACTIONS_KEY.getName());
122 if (tabs == myTabs && myTabs.myAddNavigationGroup) {
123 toShow.addAll(myTabs.myNavigationActions);
126 if (toShow.getChildrenCount() == 0) return;
128 myTabs.myActivePopup = myTabs.myActionManager.createActionPopupMenu(place, toShow).getComponent();
129 myTabs.myActivePopup.addPopupMenuListener(myTabs.myPopupListener);
131 myTabs.myActivePopup.addPopupMenuListener(myTabs);
132 myTabs.myActivePopup.show(e.getComponent(), e.getX(), e.getY());
133 myTabs.onPopup(myTabs.myPopupInfo);
137 public void setText(final SimpleColoredText text) {
138 clear(false);
139 if (text != null) {
140 text.appendToComponent(myLabel);
142 invalidateIfNeeded();
145 private void clear(final boolean invalidate) {
146 myLabel.clear();
147 myLabel.setIcon(myIcon);
149 if (invalidate) {
150 invalidateIfNeeded();
154 private void invalidateIfNeeded() {
155 if (myLabel.getSize() != null && myLabel.getSize().equals(myLabel.getPreferredSize())) return;
156 myLabel.getParent().invalidate();
158 myTabs.revalidateAndRepaint(false);
161 public void setIcon(final Icon icon) {
162 getLayeredIcon().setIcon(icon, 0);
163 invalidateIfNeeded();
166 private LayeredIcon getLayeredIcon() {
167 return myIcon;
170 public void setAttraction(boolean enabled) {
171 getLayeredIcon().setLayerEnabled(1, enabled);
174 public boolean isAttractionEnabled() {
175 return getLayeredIcon().isLayerEnabled(1);
178 public TabInfo getInfo() {
179 return myInfo;
182 public void apply(UiDecorator.UiDecoration decoration) {
183 if (decoration.getLabelFont() != null) {
184 setFont(decoration.getLabelFont());
187 Insets insets = decoration.getLabelInsets();
188 if (insets != null) {
189 Insets current = JBTabsImpl.ourDefaultDecorator.getDecoration().getLabelInsets();
190 setBorder(new EmptyBorder(getValue(current.top, insets.top), getValue(current.left, insets.left),
191 getValue(current.bottom, insets.bottom), getValue(current.right, insets.right)));
195 private int getValue(int curentValue, int newValue) {
196 return newValue != -1 ? newValue : curentValue;
199 public void setTabActions(ActionGroup group) {
200 removeOldActionPanel();
202 if (group == null) return;
204 myActionPanel = new ActionPanel(myTabs, myInfo, new Pass<MouseEvent>() {
205 public void pass(final MouseEvent event) {
206 final MouseEvent me = SwingUtilities.convertMouseEvent(event.getComponent(), event, TabLabel.this);
207 processMouseEvent(me);
211 toggleShowActions(false);
213 add(myActionPanel, BorderLayout.EAST);
215 myTabs.revalidateAndRepaint(false);
218 @Override
219 protected void processMouseEvent(final MouseEvent e) {
220 super.processMouseEvent(e);
223 private void removeOldActionPanel() {
224 if (myActionPanel != null) {
225 myActionPanel.getParent().remove(myActionPanel);
226 myActionPanel = null;
230 public boolean updateTabActions() {
231 return myActionPanel != null && myActionPanel.update();
235 private void setAttractionIcon(Icon icon) {
236 if (myIcon.getIcon(0) == null) {
237 getLayeredIcon().setIcon(null, 1);
238 myOverlayedIcon = icon;
239 } else {
240 getLayeredIcon().setIcon(icon, 1);
241 myOverlayedIcon = null;
245 public boolean repaintAttraction() {
246 if (!myTabs.myAttractions.contains(myInfo)) {
247 if (getLayeredIcon().isLayerEnabled(1)) {
248 getLayeredIcon().setLayerEnabled(1, false);
249 setAttractionIcon(null);
250 invalidateIfNeeded();
251 return true;
253 return false;
256 boolean needsUpdate = false;
258 if (getLayeredIcon().getIcon(1) != myInfo.getAlertIcon()) {
259 setAttractionIcon(myInfo.getAlertIcon());
260 needsUpdate = true;
263 int maxInitialBlinkCount = 5;
264 int maxRefireBlinkCount = maxInitialBlinkCount + 2;
265 if (myInfo.getBlinkCount() < maxInitialBlinkCount && myInfo.isAlertRequested()) {
266 getLayeredIcon().setLayerEnabled(1, !getLayeredIcon().isLayerEnabled(1));
267 if (myInfo.getBlinkCount() == 0) {
268 needsUpdate = true;
270 myInfo.setBlinkCount(myInfo.getBlinkCount() + 1);
272 if (myInfo.getBlinkCount() == maxInitialBlinkCount) {
273 myInfo.resetAlertRequest();
276 repaint();
278 else {
279 if (myInfo.getBlinkCount() < maxRefireBlinkCount && myInfo.isAlertRequested()) {
280 getLayeredIcon().setLayerEnabled(1, !getLayeredIcon().isLayerEnabled(1));
281 myInfo.setBlinkCount(myInfo.getBlinkCount() + 1);
283 if (myInfo.getBlinkCount() == maxRefireBlinkCount) {
284 myInfo.setBlinkCount(maxInitialBlinkCount);
285 myInfo.resetAlertRequest();
288 repaint();
290 else {
291 needsUpdate = !getLayeredIcon().isLayerEnabled(1);
292 getLayeredIcon().setLayerEnabled(1, true);
296 invalidateIfNeeded();
298 return needsUpdate;
301 protected void paintChildren(final Graphics g) {
302 super.paintChildren(g);
304 if (myOverlayedIcon == null || myLabel.getParent() == null) return;
306 final Rectangle textBounds = SwingUtilities.convertRectangle(myLabel.getParent(), myLabel.getBounds(), this);
307 if (getLayeredIcon().isLayerEnabled(1)) {
309 final int top = (getSize().height - myOverlayedIcon.getIconHeight()) / 2;
311 myOverlayedIcon.paintIcon(this, g, textBounds.x - myOverlayedIcon.getIconWidth() / 2, top);
316 public void setTabActionsAutoHide(final boolean autoHide) {
317 if (myActionPanel == null || myActionPanel.isAutoHide() == autoHide) {
318 return;
321 myActionPanel.setAutoHide(autoHide);
324 public void toggleShowActions(boolean show) {
325 if (myActionPanel != null) {
326 myActionPanel.toggleShowActtions(show);