sticky documentation popup [take 1]
[fedora-idea.git] / platform / platform-impl / src / com / intellij / openapi / wm / impl / TitlePanel.java
blobddfce76f47ad706624e201e48926ee63909593b4
1 /*
2 * Copyright 2000-2009 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package com.intellij.openapi.wm.impl;
18 import com.intellij.openapi.util.IconLoader;
19 import com.intellij.ui.components.panels.NonOpaquePanel;
20 import com.intellij.util.Alarm;
21 import com.intellij.util.ui.UIUtil;
23 import javax.swing.*;
24 import javax.swing.border.EmptyBorder;
25 import java.awt.*;
27 /**
28 * @author Anton Katilin
29 * @author Vladimir Kondratyev
31 public final class TitlePanel extends JPanel {
32 private static final int DELAY = 5; // Delay between frames
33 private static final int TOTAL_FRAME_COUNT = 7; // Total number of frames in animation sequence
35 private int myCurrentFrame;
37 public final static Color CNT_ENABLE_COLOR = new Color(105, 128, 180);
38 public final static Color BND_ENABLE_COLOR = CNT_ENABLE_COLOR.brighter();
40 private final static Color BND_DISABLE_COLOR = new Color(184, 184, 184); //new Color(160, 160, 160);
41 private final static Color CNT_DISABLE_COLOR = new Color(184, 184, 184);
44 private float myBndStartRed, myBndStartGreen, myBndStartBlue; // start boundary color for animation
45 private float myBndEndRed, myBndEndGreen, myBndEndBlue; // end boundary color for animation
46 private Color myBndColor; // current boundary color
48 private float myCntStartRed, myCntStartGreen, myCntStartBlue; // start center color for animation
49 private float myCntEndRed, myCntEndGreen, myCntEndBlue; // end center color for animation
50 private Color myCntColor; // current center color
52 private final Alarm myFrameTicker; // Determines moments of rendering of next frame
53 private final MyAnimator myAnimator; // Renders panel's color
54 private boolean myActive = true;
55 private JComponent mySideButtons;
57 public static final Color BUTTON_SEPARATOR_COLOR = Color.white;
58 private final Icon mySeparatorActive = IconLoader.getIcon("/general/separator.png");
59 private final Icon mySeparatorInactive = IconLoader.getIcon("/general/inactiveSeparator.png");
61 public final static Color ACTIVE_SIDE_BUTTON_BG = new Color(179, 197, 231);
62 public final static Color INACTIVE_SIDE_BUTTON_BG = new Color(200, 200, 200);
63 public static final int STRUT = 1;
65 TitlePanel() {
66 super(new BorderLayout());
68 myFrameTicker = new Alarm();
69 myAnimator = new MyAnimator();
70 setLayout(new BorderLayout());
72 setupColors(false);
74 myCurrentFrame = TOTAL_FRAME_COUNT;
75 updateColor();
79 public void addTitle(JComponent component) {
80 add(component, BorderLayout.CENTER);
83 public final void setActive(final boolean active, boolean animate) {
84 if (active == myActive) {
85 return;
88 myActive = active;
89 myFrameTicker.cancelAllRequests();
90 if (myCurrentFrame > 0) { // reverse rendering
91 myCurrentFrame = TOTAL_FRAME_COUNT - myCurrentFrame;
94 setupColors(active);
96 if (animate) {
97 myFrameTicker.addRequest(myAnimator, DELAY);
99 else {
100 myCurrentFrame = TOTAL_FRAME_COUNT;
101 updateColor();
105 private void setupColors(final boolean active) {
106 if (active) {
108 // Boundary color
110 myBndStartRed = BND_DISABLE_COLOR.getRed();
111 myBndStartGreen = BND_DISABLE_COLOR.getGreen();
112 myBndStartBlue = BND_DISABLE_COLOR.getBlue();
114 myBndEndRed = BND_ENABLE_COLOR.getRed();
115 myBndEndGreen = BND_ENABLE_COLOR.getGreen();
116 myBndEndBlue = BND_ENABLE_COLOR.getBlue();
118 // Center color
120 myCntStartRed = CNT_DISABLE_COLOR.getRed();
121 myCntStartGreen = CNT_DISABLE_COLOR.getGreen();
122 myCntStartBlue = CNT_DISABLE_COLOR.getBlue();
124 myCntEndRed = CNT_ENABLE_COLOR.getRed();
125 myCntEndGreen = CNT_ENABLE_COLOR.getGreen();
126 myCntEndBlue = CNT_ENABLE_COLOR.getBlue();
128 else {
130 // Boundary color
132 myBndStartRed = BND_ENABLE_COLOR.getRed();
133 myBndStartGreen = BND_ENABLE_COLOR.getGreen();
134 myBndStartBlue = BND_ENABLE_COLOR.getBlue();
136 myBndEndRed = BND_DISABLE_COLOR.getRed();
137 myBndEndGreen = BND_DISABLE_COLOR.getGreen();
138 myBndEndBlue = BND_DISABLE_COLOR.getBlue();
140 // Center color
142 myCntStartRed = CNT_ENABLE_COLOR.getRed();
143 myCntStartGreen = CNT_ENABLE_COLOR.getGreen();
144 myCntStartBlue = CNT_ENABLE_COLOR.getBlue();
146 myCntEndRed = CNT_DISABLE_COLOR.getRed();
147 myCntEndGreen = CNT_DISABLE_COLOR.getGreen();
148 myCntEndBlue = CNT_DISABLE_COLOR.getBlue();
152 private void updateColor() {
154 // Update boundary color
156 final int bndRed = (int) (myBndStartRed + (float) myCurrentFrame * (myBndEndRed - myBndStartRed) / TOTAL_FRAME_COUNT);
157 final int bndGreen = (int) (myBndStartGreen + (float) myCurrentFrame * (myBndEndGreen - myBndStartGreen) / TOTAL_FRAME_COUNT);
158 final int bndBlue = (int) (myBndStartBlue + (float) myCurrentFrame * (myBndEndBlue - myBndStartBlue) / TOTAL_FRAME_COUNT);
159 myBndColor = new Color(Math.max(0, Math.min(bndRed, 255)),
160 Math.max(0, Math.min(bndGreen, 255)),
161 Math.max(0, Math.min(bndBlue, 255)));
163 // Update center color
165 final int cntRed = (int) (myCntStartRed + (float) myCurrentFrame * (myCntEndRed - myCntStartRed) / TOTAL_FRAME_COUNT);
166 final int cntGreen = (int) (myCntStartGreen + (float) myCurrentFrame * (myCntEndGreen - myCntStartGreen) / TOTAL_FRAME_COUNT);
167 final int cntBlue = (int) (myCntStartBlue + (float) myCurrentFrame * (myCntEndBlue - myCntStartBlue) / TOTAL_FRAME_COUNT);
168 myCntColor = new Color(Math.max(0, Math.min(cntRed, 255)),
169 Math.max(0, Math.min(cntGreen, 255)),
170 Math.max(0, Math.min(cntBlue, 255)));
174 @Override
175 protected void addImpl(Component comp, Object constraints, int index) {
176 UIUtil.removeQuaquaVisualMarginsIn(comp);
177 super.addImpl(comp, constraints, index);
180 protected final void paintComponent(final Graphics g) {
181 super.paintComponent(g);
183 final Graphics2D g2d = (Graphics2D) g;
186 g2d.setPaint(new GradientPaint(0, STRUT, myBndColor, 0, getHeight(), myCntColor));
187 if (mySideButtons.isVisible()) {
188 final Rectangle sideRec = SwingUtilities.convertRectangle(mySideButtons.getParent(), mySideButtons.getBounds(), this);
189 g2d.fillRect(0, STRUT, getWidth() - sideRec.width, getHeight());
191 g2d.setColor(UIUtil.getBorderInactiveColor());
192 final Color buttonInnerColor = myActive ? ACTIVE_SIDE_BUTTON_BG : INACTIVE_SIDE_BUTTON_BG;
193 g2d.setPaint(new GradientPaint(sideRec.x, sideRec.y, Color.white, sideRec.x, (int)sideRec.getMaxY() - 1, buttonInnerColor));
194 g2d.fillRect(sideRec.x + 2, sideRec.y, sideRec.width - 2, sideRec.height);
197 Icon separator = myActive ? mySeparatorActive : mySeparatorInactive;
198 separator.paintIcon(this, g, sideRec.x, sideRec.y);
200 } else {
201 g2d.fillRect(0, STRUT, getWidth(), getHeight());
204 public JComponent getSideButtonsComponent() {
205 return mySideButtons;
208 public void addButtons(final JComponent buttons, JComponent sideButtons) {
209 mySideButtons = sideButtons;
210 mySideButtons.setBorder(new EmptyBorder(0, 6, 0, 6));
212 final JPanel allButtons = new JPanel(new BorderLayout());
213 allButtons.setOpaque(false);
215 UIUtil.removeQuaquaVisualMarginsIn(buttons);
216 UIUtil.removeQuaquaVisualMarginsIn(sideButtons);
218 allButtons.add(buttons, BorderLayout.CENTER);
219 allButtons.add(mySideButtons, BorderLayout.EAST);
221 final NonOpaquePanel wrapper = new NonOpaquePanel(new BorderLayout());
222 wrapper.add(Box.createVerticalStrut(STRUT), BorderLayout.NORTH);
223 wrapper.add(allButtons, BorderLayout.CENTER);
225 add(wrapper, BorderLayout.EAST);
228 private final class MyAnimator implements Runnable {
229 public void run() {
230 updateColor();
231 paintImmediately(0, 0, getWidth(), getHeight());
232 if (myCurrentFrame <= TOTAL_FRAME_COUNT) {
233 myCurrentFrame++;
234 myFrameTicker.addRequest(this, DELAY);
236 else {
237 myFrameTicker.cancelAllRequests();