/platform/platform-api/src/com/intellij/ui/tabs/impl/TabLabel.java
https://bitbucket.org/nbargnesi/idea · Java · 556 lines · 435 code · 106 blank · 15 comment · 113 complexity · 649aabc8b7e47f61ff171dcb37f8e3d3 MD5 · raw file
- /*
- * Copyright 2000-2012 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.intellij.ui.tabs.impl;
- import com.intellij.ide.DataManager;
- import com.intellij.ide.ui.UISettings;
- import com.intellij.openapi.actionSystem.ActionGroup;
- import com.intellij.openapi.actionSystem.ActionPlaces;
- import com.intellij.openapi.actionSystem.DefaultActionGroup;
- import com.intellij.openapi.util.Pass;
- import com.intellij.openapi.util.SystemInfo;
- import com.intellij.ui.InplaceButton;
- import com.intellij.ui.LayeredIcon;
- import com.intellij.ui.SimpleColoredComponent;
- import com.intellij.ui.SimpleColoredText;
- import com.intellij.ui.components.panels.Wrapper;
- import com.intellij.ui.tabs.JBTabsPosition;
- import com.intellij.ui.tabs.TabInfo;
- import com.intellij.ui.tabs.TabsUtil;
- import com.intellij.ui.tabs.UiDecorator;
- import com.intellij.ui.tabs.impl.table.TableLayout;
- import com.intellij.util.PairConsumer;
- import com.intellij.util.ui.Centerizer;
- import com.intellij.util.ui.UIUtil;
- import org.jetbrains.annotations.Nullable;
- import javax.swing.*;
- import javax.swing.border.EmptyBorder;
- import java.awt.*;
- import java.awt.event.MouseAdapter;
- import java.awt.event.MouseEvent;
- import java.awt.image.BufferedImage;
- public class TabLabel extends JPanel {
- protected final SimpleColoredComponent myLabel = new SimpleColoredComponent() {
- @Override
- protected boolean shouldDrawMacShadow() {
- return SystemInfo.isMac && !UIUtil.isUnderDarcula();
- }
- };
-
- private final LayeredIcon myIcon;
- private Icon myOverlayedIcon;
- private final TabInfo myInfo;
- protected ActionPanel myActionPanel;
- private boolean myCentered;
- private final Wrapper myLabelPlaceholder = new Wrapper(false);
- private final JBTabsImpl myTabs;
- private BufferedImage myInactiveStateImage;
- private Rectangle myLastPaintedInactiveImageBounds;
- public TabLabel(JBTabsImpl tabs, final TabInfo info) {
- super(false);
- myTabs = tabs;
- myInfo = info;
- myLabel.setOpaque(false);
- myLabel.setBorder(null);
- myLabel.setIconTextGap(tabs.isEditorTabs() ? 2 : new JLabel().getIconTextGap());
- myLabel.setIconOpaque(false);
- myLabel.setIpad(new Insets(0, 0, 0, 0));
- setOpaque(false);
- setLayout(new BorderLayout());
- myLabelPlaceholder.setOpaque(false);
- add(myLabelPlaceholder, BorderLayout.CENTER);
- setAlignmentToCenter(true);
- myIcon = new LayeredIcon(2);
- addMouseListener(new MouseAdapter() {
- public void mousePressed(final MouseEvent e) {
- if (JBTabsImpl.isSelectionClick(e, false) && myInfo.isEnabled()) {
- final TabInfo selectedInfo = myTabs.getSelectedInfo();
- if (selectedInfo != myInfo) {
- myInfo.setPreviousSelection(selectedInfo);
- }
- Component c = SwingUtilities.getDeepestComponentAt(e.getComponent(), e.getX(), e.getY());
- if (c instanceof InplaceButton) return;
- myTabs.select(info, true);
- }
- else {
- handlePopup(e);
- }
- }
- public void mouseClicked(final MouseEvent e) {
- handlePopup(e);
- }
- public void mouseReleased(final MouseEvent e) {
- myInfo.setPreviousSelection(null);
- handlePopup(e);
- }
- });
- }
- @Override
- public Insets getInsets() {
- Insets insets = super.getInsets();
- if (myTabs.isEditorTabs()) {
- if (UISettings.getInstance().SHOW_CLOSE_BUTTON) {
- return new Insets(insets.top, insets.left, insets.bottom, 3);
- }
- }
-
- return insets;
- }
- public void setAlignmentToCenter(boolean toCenter) {
- if (myCentered == toCenter && myLabel.getParent() != null) return;
- myLabelPlaceholder.removeAll();
- if (toCenter) {
- final Centerizer center = new Centerizer(myLabel);
- myLabelPlaceholder.setContent(center);
- } else {
- myLabelPlaceholder.setContent(myLabel);
- }
- myCentered = toCenter;
- }
- public void paintOffscreen(Graphics g) {
- synchronized(getTreeLock()) {
- validateTree();
- }
- doPaint(g);
- }
- public void paint(final Graphics g) {
- if (myTabs.isDropTarget(myInfo)) return;
- if (myTabs.getSelectedInfo() != myInfo) {
- doPaint(g);
- }
- }
- @Override
- public void setBounds(Rectangle r) {
- super.setBounds(r);
- }
- @Override
- public void setBounds(int x, int y, int width, int height) {
- super.setBounds(x, y, width, height);
- }
- public void paintImage(Graphics g) {
- final Rectangle b = getBounds();
- final Graphics lG = g.create(b.x, b.y, b.width, b.height);
- try {
- lG.setColor(Color.red);
- doPaint(lG);
- }
- finally {
- lG.dispose();
- }
- }
- public void doTranslate(PairConsumer<Integer, Integer> consumer) {
- final JBTabsPosition pos = myTabs.getTabsPosition();
- int dX = 0;
- int dXs = 0;
- int dY = 0;
- int dYs = 0;
- int selected = getSelectedOffset();
- int plain = getNonSelectedOffset();
- switch (pos) {
- case bottom:
- dY = -plain;
- dYs = -selected;
- break;
- case left:
- dX = plain;
- dXs = selected;
- break;
- case right:
- dX = -plain;
- dXs = -selected;
- break;
- case top:
- dY = plain;
- dYs = selected;
- break;
- }
-
- if (!myTabs.isDropTarget(myInfo)) {
- if (myTabs.getSelectedInfo() != myInfo) {
- consumer.consume(dX, dY);
- } else {
- consumer.consume(dXs, dYs);
- }
- }
- }
- private void doPaint(final Graphics g) {
- doTranslate(new PairConsumer<Integer, Integer>() {
- @Override
- public void consume(Integer x, Integer y) {
- g.translate(x, y);
- }
- });
- super.paint(g);
- doTranslate(new PairConsumer<Integer, Integer>() {
- @Override
- public void consume(Integer x, Integer y) {
- g.translate(-x, -y);
- }
- });
- }
- protected int getNonSelectedOffset() {
- if (myTabs.isEditorTabs()) {
- int offset = (TabsUtil.ACTIVE_TAB_UNDERLINE_HEIGHT / 2);
- if (myTabs.isSingleRow()) {
- return myTabs.getTabsPosition() == JBTabsPosition.bottom ? -(offset + 1) : -offset + 1;
- } else {
- return ((TableLayout)myTabs.getEffectiveLayout()).isLastRow(getInfo()) ? -offset + 1 : offset - 1;
- }
- }
-
- return 2;
- }
- protected int getSelectedOffset() {
- return myTabs.isEditorTabs() ? -(TabsUtil.ACTIVE_TAB_UNDERLINE_HEIGHT / 2) + 1 : 1;
- }
- @Override
- public Dimension getPreferredSize() {
- final Dimension size = super.getPreferredSize();
- if (myActionPanel != null && !myActionPanel.isVisible()) {
- final Dimension actionPanelSize = myActionPanel.getPreferredSize();
- size.width += actionPanelSize.width;
- }
- final JBTabsPosition pos = myTabs.getTabsPosition();
- switch (pos) {
- case top: case bottom: size.height += myTabs.isEditorTabs() ? TabsUtil.ACTIVE_TAB_UNDERLINE_HEIGHT : getSelectedOffset(); break;
- case left: case right: size.width += getSelectedOffset(); break;
- }
- return size;
- }
- private void handlePopup(final MouseEvent e) {
- if (e.getClickCount() != 1 || !e.isPopupTrigger()) return;
- if (e.getX() < 0 || e.getX() >= e.getComponent().getWidth() || e.getY() < 0 || e.getY() >= e.getComponent().getHeight()) return;
- String place = myTabs.getPopupPlace();
- place = place != null ? place : ActionPlaces.UNKNOWN;
- myTabs.myPopupInfo = myInfo;
- final DefaultActionGroup toShow = new DefaultActionGroup();
- if (myTabs.getPopupGroup() != null) {
- toShow.addAll(myTabs.getPopupGroup());
- toShow.addSeparator();
- }
- JBTabsImpl tabs = JBTabsImpl.NAVIGATION_ACTIONS_KEY.getData(DataManager.getInstance().getDataContext(e.getComponent(), e.getX(), e.getY()));
- if (tabs == myTabs && myTabs.myAddNavigationGroup) {
- toShow.addAll(myTabs.myNavigationActions);
- }
- if (toShow.getChildrenCount() == 0) return;
- myTabs.myActivePopup = myTabs.myActionManager.createActionPopupMenu(place, toShow).getComponent();
- myTabs.myActivePopup.addPopupMenuListener(myTabs.myPopupListener);
- myTabs.myActivePopup.addPopupMenuListener(myTabs);
- myTabs.myActivePopup.show(e.getComponent(), e.getX(), e.getY());
- }
- public void setText(final SimpleColoredText text) {
- myLabel.change(new Runnable() {
- public void run() {
- myLabel.clear();
- myLabel.setIcon(hasIcons() ? myIcon : null);
- if (text != null) {
- text.appendToComponent(myLabel);
- }
- }
- }, false);
- invalidateIfNeeded();
- }
- private void invalidateIfNeeded() {
- if (myLabel.getRootPane() == null) return;
- Dimension d = myLabel.getSize();
- Dimension pref = myLabel.getPreferredSize();
- if (d != null && d.equals(pref)) {
- return;
- }
- setInactiveStateImage(null);
- myLabel.invalidate();
- if (myActionPanel != null) {
- myActionPanel.invalidate();
- }
- myTabs.revalidateAndRepaint(false);
- }
- public void setIcon(final Icon icon) {
- setIcon(icon, 0);
- }
- private boolean hasIcons() {
- LayeredIcon layeredIcon = getLayeredIcon();
- boolean hasIcons = false;
- Icon[] layers = layeredIcon.getAllLayers();
- for (Icon layer1 : layers) {
- if (layer1 != null) {
- hasIcons = true;
- break;
- }
- }
-
- return hasIcons;
- }
-
- private void setIcon(@Nullable final Icon icon, int layer) {
- LayeredIcon layeredIcon = getLayeredIcon();
- layeredIcon.setIcon(icon, layer);
- if (hasIcons()) {
- myLabel.setIcon(layeredIcon);
- } else {
- myLabel.setIcon(null);
- }
-
- invalidateIfNeeded();
- }
- private LayeredIcon getLayeredIcon() {
- return myIcon;
- }
- public TabInfo getInfo() {
- return myInfo;
- }
- public void apply(UiDecorator.UiDecoration decoration) {
- if (decoration.getLabelFont() != null) {
- setFont(decoration.getLabelFont());
- myLabel.setFont(decoration.getLabelFont());
- }
- Insets insets = decoration.getLabelInsets();
- if (insets != null) {
- Insets current = JBTabsImpl.ourDefaultDecorator.getDecoration().getLabelInsets();
- if (current != null) {
- setBorder(
- new EmptyBorder(getValue(current.top, insets.top), getValue(current.left, insets.left), getValue(current.bottom, insets.bottom),
- getValue(current.right, insets.right)));
- }
- }
- }
- private static int getValue(int currentValue, int newValue) {
- return newValue != -1 ? newValue : currentValue;
- }
- public void setTabActions(ActionGroup group) {
- removeOldActionPanel();
- if (group == null) return;
- myActionPanel = new ActionPanel(myTabs, myInfo, new Pass<MouseEvent>() {
- public void pass(final MouseEvent event) {
- final MouseEvent me = SwingUtilities.convertMouseEvent(event.getComponent(), event, TabLabel.this);
- processMouseEvent(me);
- }
- });
- toggleShowActions(false);
- add(myActionPanel, BorderLayout.EAST);
- myTabs.revalidateAndRepaint(false);
- }
- private void removeOldActionPanel() {
- if (myActionPanel != null) {
- myActionPanel.getParent().remove(myActionPanel);
- myActionPanel = null;
- }
- }
- public boolean updateTabActions() {
- return myActionPanel != null && myActionPanel.update();
- }
- private void setAttractionIcon(@Nullable Icon icon) {
- if (myIcon.getIcon(0) == null) {
- setIcon(null, 1);
- myOverlayedIcon = icon;
- } else {
- setIcon(icon, 1);
- myOverlayedIcon = null;
- }
- }
- public boolean repaintAttraction() {
- if (!myTabs.myAttractions.contains(myInfo)) {
- if (getLayeredIcon().isLayerEnabled(1)) {
- getLayeredIcon().setLayerEnabled(1, false);
- setAttractionIcon(null);
- invalidateIfNeeded();
- return true;
- }
- return false;
- }
- boolean needsUpdate = false;
- if (getLayeredIcon().getIcon(1) != myInfo.getAlertIcon()) {
- setAttractionIcon(myInfo.getAlertIcon());
- needsUpdate = true;
- }
- int maxInitialBlinkCount = 5;
- int maxRefireBlinkCount = maxInitialBlinkCount + 2;
- if (myInfo.getBlinkCount() < maxInitialBlinkCount && myInfo.isAlertRequested()) {
- getLayeredIcon().setLayerEnabled(1, !getLayeredIcon().isLayerEnabled(1));
- if (myInfo.getBlinkCount() == 0) {
- needsUpdate = true;
- }
- myInfo.setBlinkCount(myInfo.getBlinkCount() + 1);
- if (myInfo.getBlinkCount() == maxInitialBlinkCount) {
- myInfo.resetAlertRequest();
- }
- repaint();
- }
- else {
- if (myInfo.getBlinkCount() < maxRefireBlinkCount && myInfo.isAlertRequested()) {
- getLayeredIcon().setLayerEnabled(1, !getLayeredIcon().isLayerEnabled(1));
- myInfo.setBlinkCount(myInfo.getBlinkCount() + 1);
- if (myInfo.getBlinkCount() == maxRefireBlinkCount) {
- myInfo.setBlinkCount(maxInitialBlinkCount);
- myInfo.resetAlertRequest();
- }
- repaint();
- }
- else {
- needsUpdate = !getLayeredIcon().isLayerEnabled(1);
- getLayeredIcon().setLayerEnabled(1, true);
- }
- }
- invalidateIfNeeded();
- return needsUpdate;
- }
- protected void paintChildren(final Graphics g) {
- super.paintChildren(g);
- if (myOverlayedIcon == null || myLabel.getParent() == null) return;
- final Rectangle textBounds = SwingUtilities.convertRectangle(myLabel.getParent(), myLabel.getBounds(), this);
- if (getLayeredIcon().isLayerEnabled(1)) {
- final int top = (getSize().height - myOverlayedIcon.getIconHeight()) / 2;
- myOverlayedIcon.paintIcon(this, g, textBounds.x - myOverlayedIcon.getIconWidth() / 2, top);
- }
- }
- public void setTabActionsAutoHide(final boolean autoHide) {
- if (myActionPanel == null || myActionPanel.isAutoHide() == autoHide) {
- return;
- }
- myActionPanel.setAutoHide(autoHide);
- }
- public void toggleShowActions(boolean show) {
- if (myActionPanel != null) {
- myActionPanel.toggleShowActions(show);
- }
- }
- public void setActionPanelVisible(boolean visible) {
- if (myActionPanel != null) {
- myActionPanel.setVisible(visible);
- }
- }
- @Override
- public String toString() {
- return myInfo.getText();
- }
- public void setTabEnabled(boolean enabled) {
- myLabel.setEnabled(enabled);
- }
- @Nullable
- public BufferedImage getInactiveStateImage(Rectangle effectiveBounds) {
- BufferedImage img = null;
- if (myLastPaintedInactiveImageBounds != null && myLastPaintedInactiveImageBounds.getSize().equals(effectiveBounds.getSize())) {
- img = myInactiveStateImage;
- } else {
- setInactiveStateImage(null);
- }
- myLastPaintedInactiveImageBounds = effectiveBounds;
- return img;
- }
- public void setInactiveStateImage(@Nullable BufferedImage img) {
- if (myInactiveStateImage != null && img != myInactiveStateImage) {
- myInactiveStateImage.flush();
- }
- myInactiveStateImage = img;
- }
- }