blob: 4609acf0fd4b47c7b4906a9752cee6e0257f8159 [file] [log] [blame]
/*
* 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.intellij.openapi.wm.impl.status;
import com.intellij.icons.AllIcons;
import com.intellij.ide.IdeEventQueue;
import com.intellij.ide.ui.UISettings;
import com.intellij.ide.ui.UISettingsListener;
import com.intellij.ide.util.PropertiesComponent;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.ui.popup.Balloon;
import com.intellij.openapi.ui.popup.JBPopup;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.ui.popup.PopupChooserBuilder;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.wm.*;
import com.intellij.openapi.wm.impl.IdeFrameImpl;
import com.intellij.ui.GotItMessage;
import com.intellij.ui.IdeBorderFactory;
import com.intellij.ui.UIBundle;
import com.intellij.ui.awt.RelativePoint;
import com.intellij.ui.components.JBLabel;
import com.intellij.ui.components.JBList;
import com.intellij.util.Alarm;
import com.intellij.util.ui.BaseButtonBehavior;
import com.intellij.util.ui.TimedDeadzone;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
/**
* @author Konstantin Bulenkov
*/
class ToolWindowsWidget extends JLabel implements CustomStatusBarWidget, StatusBarWidget, Disposable,
UISettingsListener, PropertyChangeListener {
private final Alarm myAlarm;
private StatusBar myStatusBar;
private JBPopup popup;
private boolean wasExited = false;
ToolWindowsWidget(Disposable parent) {
new BaseButtonBehavior(this, TimedDeadzone.NULL) {
@Override
protected void execute(MouseEvent e) {
performAction();
}
}.setActionTrigger(MouseEvent.MOUSE_PRESSED);
IdeEventQueue.getInstance().addDispatcher(new IdeEventQueue.EventDispatcher() {
@Override
public boolean dispatch(AWTEvent e) {
if (e instanceof MouseEvent) {
MouseEvent mouseEvent = (MouseEvent)e;
if (mouseEvent.getComponent() == null || !SwingUtilities.isDescendingFrom(mouseEvent.getComponent(), SwingUtilities.getWindowAncestor(ToolWindowsWidget.this))) {
return false;
}
if (e.getID() == MouseEvent.MOUSE_MOVED && isShowing()) {
Point p = mouseEvent.getLocationOnScreen();
Point screen = ToolWindowsWidget.this.getLocationOnScreen();
if (new Rectangle(screen.x - 4, screen.y - 2, getWidth() + 4, getHeight() + 4).contains(p)) {
mouseEntered();
wasExited = false;
} else {
if (!wasExited) {
wasExited = mouseExited(p);
}
}
} else if (e.getID() == MouseEvent.MOUSE_EXITED) {
//mouse exits WND
mouseExited(mouseEvent.getLocationOnScreen());
}
}
return false;
}
}, parent);
UISettings.getInstance().addUISettingsListener(this, this);
KeyboardFocusManager.getCurrentKeyboardFocusManager().addPropertyChangeListener("focusOwner", this);
myAlarm = new Alarm(parent);
}
public boolean mouseExited(Point currentLocationOnScreen) {
myAlarm.cancelAllRequests();
if (popup != null && popup.isVisible()) {
final Point screen = popup.getLocationOnScreen();
final Rectangle popupScreenRect = new Rectangle(screen.x, screen.y, popup.getSize().width, popup.getSize().height);
if (! popupScreenRect.contains(currentLocationOnScreen)) {
myAlarm.cancelAllRequests();
myAlarm.addRequest(new Runnable() {
@Override
public void run() {
if (popup != null && popup.isVisible()) {
popup.cancel();
}
}
}, 300);
return true;
}
}
return false;
}
public void mouseEntered() {
if (myAlarm.getActiveRequestCount() == 0) {
myAlarm.addRequest(new Runnable() {
@Override
public void run() {
DefaultListModel model = new DefaultListModel();
final IdeFrameImpl frame = UIUtil.getParentOfType(IdeFrameImpl.class, ToolWindowsWidget.this);
if (frame == null) return;
final ToolWindowManager toolWindowManager = ToolWindowManager.getInstance(frame.getProject());
for (String id : toolWindowManager.getToolWindowIds()) {
final ToolWindow tw = toolWindowManager.getToolWindow(id);
if (tw.isAvailable()) {
model.addElement(tw);
}
}
final JBList list = new JBList(model);
list.setCellRenderer(new ListCellRenderer() {
final JBLabel label = new JBLabel();
@Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
final ToolWindow toolWindow = (ToolWindow)value;
label.setText(toolWindow.getStripeTitle());
label.setIcon(toolWindow.getIcon());
label.setBorder(IdeBorderFactory.createEmptyBorder(4, 10, 4, 10));
label.setForeground(UIUtil.getListForeground(isSelected));
label.setBackground(UIUtil.getListBackground(isSelected));
final JPanel panel = new JPanel(new BorderLayout());
panel.add(label, BorderLayout.CENTER);
panel.setBackground(UIUtil.getListBackground(isSelected));
return panel;
}
});
final Dimension size = list.getPreferredSize();
final JComponent c = ToolWindowsWidget.this;
final Insets padding = UIUtil.getListViewportPadding();
final RelativePoint point = new RelativePoint(c, new Point(-4, -padding.top - padding.bottom -4 - size.height + (SystemInfo.isMac ? 2 : 0)));
if (popup != null && popup.isVisible()) {
return;
}
list.setSelectedIndex(list.getItemsCount() - 1);
PopupChooserBuilder builder = JBPopupFactory.getInstance().createListPopupBuilder(list);
popup = builder
.setAutoselectOnMouseMove(true)
.setRequestFocus(false)
.setItemChoosenCallback(new Runnable() {
@Override
public void run() {
if (popup != null) popup.closeOk(null);
final Object value = list.getSelectedValue();
if (value instanceof ToolWindow) {
((ToolWindow)value).activate(null, true, true);
}
}
})
.createPopup();
popup.show(point);
}
}, 300);
}
}
@Override
public void addNotify() {
super.addNotify();
final String key = "toolwindow.stripes.buttons.info.shown";
if (UISettings.getInstance().HIDE_TOOL_STRIPES && !PropertiesComponent.getInstance().isTrueValue(key)) {
PropertiesComponent.getInstance().setValue(key, String.valueOf(true));
final Alarm alarm = new Alarm();
alarm.addRequest(new Runnable() {
@Override
public void run() {
GotItMessage.createMessage(UIBundle.message("tool.window.quick.access.title"), UIBundle.message(
"tool.window.quick.access.message"))
.setDisposable(ToolWindowsWidget.this)
.show(new RelativePoint(ToolWindowsWidget.this, new Point(10, 0)), Balloon.Position.above);
Disposer.dispose(alarm);
}
}, 20000);
}
}
@Override
public void propertyChange(PropertyChangeEvent evt) {
updateIcon();
}
@Override
public void uiSettingsChanged(UISettings source) {
updateIcon();
}
private void performAction() {
if (isActive()) {
UISettings.getInstance().HIDE_TOOL_STRIPES = !UISettings.getInstance().HIDE_TOOL_STRIPES;
UISettings.getInstance().fireUISettingsChanged();
}
}
private void updateIcon() {
setToolTipText(null);
if (isActive()) {
boolean changes = false;
if (!isVisible()) {
setVisible(true);
changes = true;
}
Icon icon = UISettings.getInstance().HIDE_TOOL_STRIPES ? AllIcons.General.TbShown : AllIcons.General.TbHidden;
if (icon != getIcon()) {
setIcon(icon);
changes = true;
}
//Set<Integer> vks = ToolWindowManagerImpl.getActivateToolWindowVKs();
//String text = "Click to show or hide the tool window bars";
//if (vks.size() == 1) {
// Integer stroke = vks.iterator().next();
// String keystrokeText = KeymapUtil.getKeystrokeText(KeyStroke.getKeyStroke(stroke.intValue(), 0));
// text += ".\nDouble-press and hold " + keystrokeText + " to show tool window bars when hidden.";
//}
//if (!text.equals(getToolTipText())) {
// setToolTipText(text);
// changes = true;
//}
if (changes) {
revalidate();
repaint();
}
}
else {
setVisible(false);
setToolTipText(null);
}
}
private boolean isActive() {
return myStatusBar != null && myStatusBar.getFrame() != null && myStatusBar.getFrame().getProject() != null && Registry
.is("ide.windowSystem.showTooWindowButtonsSwitcher");
}
@Override
public JComponent getComponent() {
return this;
}
@NotNull
@Override
public String ID() {
return "ToolWindows Widget";
}
@Override
public WidgetPresentation getPresentation(@NotNull PlatformType type) {
return null;
}
@Override
public void install(@NotNull StatusBar statusBar) {
myStatusBar = statusBar;
updateIcon();
}
@Override
public void dispose() {
Disposer.dispose(this);
KeyboardFocusManager.getCurrentKeyboardFocusManager().removePropertyChangeListener("focusOwner", this);
myStatusBar = null;
popup = null;
}
}