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
.openapi
.util
.SystemInfo
;
9 import com
.intellij
.ui
.LayeredIcon
;
10 import com
.intellij
.ui
.SimpleColoredComponent
;
11 import com
.intellij
.ui
.SimpleColoredText
;
12 import com
.intellij
.ui
.components
.panels
.Wrapper
;
13 import com
.intellij
.ui
.tabs
.JBTabsPosition
;
14 import com
.intellij
.ui
.tabs
.TabInfo
;
15 import com
.intellij
.ui
.tabs
.UiDecorator
;
16 import com
.intellij
.util
.ui
.Centerizer
;
19 import javax
.swing
.border
.EmptyBorder
;
21 import java
.awt
.event
.MouseAdapter
;
22 import java
.awt
.event
.MouseEvent
;
23 import java
.awt
.image
.BufferedImage
;
25 public class TabLabel
extends JPanel
{
26 private final SimpleColoredComponent myLabel
= new SimpleColoredComponent();
27 private final LayeredIcon myIcon
;
28 private Icon myOverlayedIcon
;
30 private final TabInfo myInfo
;
31 private ActionPanel myActionPanel
;
32 private boolean myCentered
;
34 private final Wrapper myLabelPlaceholder
= new Wrapper();
35 private final JBTabsImpl myTabs
;
37 private BufferedImage myImage
;
38 private BufferedImage myInactiveStateImage
;
40 public TabLabel(JBTabsImpl tabs
, final TabInfo info
) {
43 myLabel
.setOpaque(false);
44 myLabel
.setBorder(null);
45 myLabel
.setIconTextGap(new JLabel().getIconTextGap());
46 myLabel
.setIconOpaque(false);
47 myLabel
.setIpad(new Insets(0, 0, 0, 0));
49 setLayout(new BorderLayout());
52 myLabelPlaceholder
.setOpaque(false);
53 add(myLabelPlaceholder
, BorderLayout
.CENTER
);
55 setAligmentToCenter(true);
57 myIcon
= new LayeredIcon(2);
58 myLabel
.setIcon(myIcon
);
60 addMouseListener(new MouseAdapter() {
61 public void mousePressed(final MouseEvent e
) {
62 if (myTabs
.isSelectionClick(e
, false) && myInfo
.isEnabled()) {
63 myTabs
.select(info
, true);
70 public void mouseClicked(final MouseEvent e
) {
74 public void mouseReleased(final MouseEvent e
) {
80 public void setAligmentToCenter(boolean toCenter
) {
81 if (myCentered
== toCenter
&& myLabel
.getParent() != null) return;
83 myLabelPlaceholder
.removeAll();
86 final Centerizer center
= new Centerizer(myLabel
);
87 myLabelPlaceholder
.setContent(center
);
89 myLabelPlaceholder
.setContent(myLabel
);
92 myCentered
= toCenter
;
95 public void paint(final Graphics g
) {
96 if (myTabs
.getSelectedInfo() != myInfo
) {
99 } else if (!SystemInfo
.isMac
) {
100 myImage
= new BufferedImage(getWidth(), getHeight(), BufferedImage
.TYPE_INT_ARGB
);
101 final Graphics2D lg
= myImage
.createGraphics();
107 public void paintImage(Graphics g
) {
108 final Rectangle b
= getBounds();
109 if (myImage
!= null) {
110 g
.drawImage(myImage
, b
.x
, b
.y
, getWidth(), getHeight(), null);
112 final Graphics lG
= g
.create(b
.x
, b
.y
, b
.width
, b
.height
);
114 lG
.setColor(Color
.red
);
123 private void doPaint(Graphics g
) {
124 final JBTabsPosition pos
= myTabs
.getTabsPosition();
126 int dX
= 0, dXs
= 0, dY
= 0, dYs
= 0;
127 int selected
= 1, plain
= 2;
148 if (myTabs
.getSelectedInfo() != myInfo
) {
151 g
.translate(dXs
, dYs
);
156 if (myTabs
.getSelectedInfo() != myInfo
) {
157 g
.translate(dX
, -dY
);
163 private void handlePopup(final MouseEvent e
) {
164 if (e
.getClickCount() != 1 || !e
.isPopupTrigger()) return;
166 if (e
.getX() < 0 || e
.getX() >= e
.getComponent().getWidth() || e
.getY() < 0 || e
.getY() >= e
.getComponent().getHeight()) return;
168 String place
= myTabs
.getPopupPlace();
169 place
= place
!= null ? place
: ActionPlaces
.UNKNOWN
;
170 myTabs
.myPopupInfo
= myInfo
;
172 final DefaultActionGroup toShow
= new DefaultActionGroup();
173 if (myTabs
.getPopupGroup() != null) {
174 toShow
.addAll(myTabs
.getPopupGroup());
175 toShow
.addSeparator();
179 DataManager
.getInstance().getDataContext(e
.getComponent(), e
.getX(), e
.getY()).getData(JBTabsImpl
.NAVIGATION_ACTIONS_KEY
.getName());
180 if (tabs
== myTabs
&& myTabs
.myAddNavigationGroup
) {
181 toShow
.addAll(myTabs
.myNavigationActions
);
184 if (toShow
.getChildrenCount() == 0) return;
186 myTabs
.myActivePopup
= myTabs
.myActionManager
.createActionPopupMenu(place
, toShow
).getComponent();
187 myTabs
.myActivePopup
.addPopupMenuListener(myTabs
.myPopupListener
);
189 myTabs
.myActivePopup
.addPopupMenuListener(myTabs
);
190 myTabs
.myActivePopup
.show(e
.getComponent(), e
.getX(), e
.getY());
191 myTabs
.onPopup(myTabs
.myPopupInfo
);
195 public void setText(final SimpleColoredText text
) {
198 text
.appendToComponent(myLabel
);
200 invalidateIfNeeded();
203 private void clear(final boolean invalidate
) {
205 myLabel
.setIcon(myIcon
);
208 invalidateIfNeeded();
212 private void invalidateIfNeeded() {
213 if (myLabel
.getRootPane() == null) return;
215 if (myLabel
.getSize() != null && myLabel
.getSize().equals(myLabel
.getPreferredSize())) return;
217 myInactiveStateImage
= null;
218 myLabel
.getParent().invalidate();
219 myTabs
.revalidateAndRepaint(false);
222 public void setIcon(final Icon icon
) {
223 getLayeredIcon().setIcon(icon
, 0);
224 invalidateIfNeeded();
227 private LayeredIcon
getLayeredIcon() {
231 public void setAttraction(boolean enabled
) {
232 getLayeredIcon().setLayerEnabled(1, enabled
);
235 public boolean isAttractionEnabled() {
236 return getLayeredIcon().isLayerEnabled(1);
239 public TabInfo
getInfo() {
243 public void apply(UiDecorator
.UiDecoration decoration
) {
244 if (decoration
.getLabelFont() != null) {
245 setFont(decoration
.getLabelFont());
248 Insets insets
= decoration
.getLabelInsets();
249 if (insets
!= null) {
250 Insets current
= JBTabsImpl
.ourDefaultDecorator
.getDecoration().getLabelInsets();
251 setBorder(new EmptyBorder(getValue(current
.top
, insets
.top
), getValue(current
.left
, insets
.left
),
252 getValue(current
.bottom
, insets
.bottom
), getValue(current
.right
, insets
.right
)));
256 private int getValue(int curentValue
, int newValue
) {
257 return newValue
!= -1 ? newValue
: curentValue
;
260 public void setTabActions(ActionGroup group
) {
261 removeOldActionPanel();
263 if (group
== null) return;
265 myActionPanel
= new ActionPanel(myTabs
, myInfo
, new Pass
<MouseEvent
>() {
266 public void pass(final MouseEvent event
) {
267 final MouseEvent me
= SwingUtilities
.convertMouseEvent(event
.getComponent(), event
, TabLabel
.this);
268 processMouseEvent(me
);
272 toggleShowActions(false);
274 add(myActionPanel
, BorderLayout
.EAST
);
276 myTabs
.revalidateAndRepaint(false);
280 protected void processMouseEvent(final MouseEvent e
) {
281 super.processMouseEvent(e
);
284 private void removeOldActionPanel() {
285 if (myActionPanel
!= null) {
286 myActionPanel
.getParent().remove(myActionPanel
);
287 myActionPanel
= null;
291 public boolean updateTabActions() {
292 return myActionPanel
!= null && myActionPanel
.update();
296 private void setAttractionIcon(Icon icon
) {
297 if (myIcon
.getIcon(0) == null) {
298 getLayeredIcon().setIcon(null, 1);
299 myOverlayedIcon
= icon
;
301 getLayeredIcon().setIcon(icon
, 1);
302 myOverlayedIcon
= null;
306 public boolean repaintAttraction() {
307 if (!myTabs
.myAttractions
.contains(myInfo
)) {
308 if (getLayeredIcon().isLayerEnabled(1)) {
309 getLayeredIcon().setLayerEnabled(1, false);
310 setAttractionIcon(null);
311 invalidateIfNeeded();
317 boolean needsUpdate
= false;
319 if (getLayeredIcon().getIcon(1) != myInfo
.getAlertIcon()) {
320 setAttractionIcon(myInfo
.getAlertIcon());
324 int maxInitialBlinkCount
= 5;
325 int maxRefireBlinkCount
= maxInitialBlinkCount
+ 2;
326 if (myInfo
.getBlinkCount() < maxInitialBlinkCount
&& myInfo
.isAlertRequested()) {
327 getLayeredIcon().setLayerEnabled(1, !getLayeredIcon().isLayerEnabled(1));
328 if (myInfo
.getBlinkCount() == 0) {
331 myInfo
.setBlinkCount(myInfo
.getBlinkCount() + 1);
333 if (myInfo
.getBlinkCount() == maxInitialBlinkCount
) {
334 myInfo
.resetAlertRequest();
340 if (myInfo
.getBlinkCount() < maxRefireBlinkCount
&& myInfo
.isAlertRequested()) {
341 getLayeredIcon().setLayerEnabled(1, !getLayeredIcon().isLayerEnabled(1));
342 myInfo
.setBlinkCount(myInfo
.getBlinkCount() + 1);
344 if (myInfo
.getBlinkCount() == maxRefireBlinkCount
) {
345 myInfo
.setBlinkCount(maxInitialBlinkCount
);
346 myInfo
.resetAlertRequest();
352 needsUpdate
= !getLayeredIcon().isLayerEnabled(1);
353 getLayeredIcon().setLayerEnabled(1, true);
357 invalidateIfNeeded();
362 protected void paintChildren(final Graphics g
) {
363 super.paintChildren(g
);
365 if (myOverlayedIcon
== null || myLabel
.getParent() == null) return;
367 final Rectangle textBounds
= SwingUtilities
.convertRectangle(myLabel
.getParent(), myLabel
.getBounds(), this);
368 if (getLayeredIcon().isLayerEnabled(1)) {
370 final int top
= (getSize().height
- myOverlayedIcon
.getIconHeight()) / 2;
372 myOverlayedIcon
.paintIcon(this, g
, textBounds
.x
- myOverlayedIcon
.getIconWidth() / 2, top
);
377 public void setTabActionsAutoHide(final boolean autoHide
) {
378 if (myActionPanel
== null || myActionPanel
.isAutoHide() == autoHide
) {
382 myActionPanel
.setAutoHide(autoHide
);
385 public void toggleShowActions(boolean show
) {
386 if (myActionPanel
!= null) {
387 myActionPanel
.toggleShowActtions(show
);
392 public String
toString() {
393 return myInfo
.getText();
396 public void setTabEnabled(boolean enabled
) {
397 myLabel
.setEnabled(enabled
);
401 public BufferedImage
getInactiveStateImage() {
402 return myInactiveStateImage
;
405 public void setInactiveStateImage(BufferedImage img
) {
406 if (myImage
!= null && img
!= myImage
) {
409 myInactiveStateImage
= img
;