welcome screen: VCS popup shows at left under the label
[idea/community.git] / platform / platform-impl / src / com / intellij / openapi / wm / impl / welcomeScreen / WelcomePopupAction.java
1 /*
2  * Copyright 2000-2014 JetBrains s.r.o.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16 package com.intellij.openapi.wm.impl.welcomeScreen;
17
18 import com.intellij.openapi.actionSystem.*;
19 import com.intellij.openapi.project.DumbAware;
20 import com.intellij.openapi.project.Project;
21 import com.intellij.openapi.ui.popup.JBPopupFactory;
22 import com.intellij.openapi.ui.popup.ListPopup;
23 import com.intellij.openapi.wm.ex.WindowManagerEx;
24 import com.intellij.ui.popup.PopupFactoryImpl;
25
26 import javax.swing.*;
27 import java.awt.*;
28 import java.awt.event.InputEvent;
29 import java.awt.event.MouseEvent;
30
31 /**
32  * @author Vladislav.Kaznacheev
33  */
34 public abstract class WelcomePopupAction extends AnAction implements DumbAware {
35
36   protected abstract void fillActions(DefaultActionGroup group);
37
38   protected abstract String getTextForEmpty();
39
40   protected abstract String getCaption();
41
42   /**
43    * When there is only one option to choose from, this method is called to determine whether
44    * the popup should still be shown or that the option should be chosen silently.
45    *
46    * @return true to choose single option silently
47    *         false otherwise
48    */
49   protected abstract boolean isSilentlyChooseSingleOption();
50
51   public void actionPerformed(final AnActionEvent e) {
52     showPopup(e);
53   }
54
55   private void showPopup(final AnActionEvent e) {
56     final DefaultActionGroup group = new DefaultActionGroup();
57     fillActions(group);
58
59     if (group.getChildrenCount() == 1 && isSilentlyChooseSingleOption()) {
60       final AnAction[] children = group.getChildren(null);
61       children[0].actionPerformed(e);
62       return;
63     }
64
65
66     if (group.getChildrenCount() == 0) {
67       group.add(new AnAction(getTextForEmpty()) {
68         public void actionPerformed(AnActionEvent e) {
69           group.setPopup(false);
70         }
71       } );
72     }
73
74     final DataContext context = e.getDataContext();
75     final ListPopup popup = JBPopupFactory.getInstance()
76       .createActionGroupPopup(getCaption(),
77                               group,
78                               context,
79                               JBPopupFactory.ActionSelectionAid.SPEEDSEARCH,
80                               true);
81
82     JComponent contextComponent = null;
83     InputEvent inputEvent = e.getInputEvent();
84     if (inputEvent instanceof MouseEvent) {
85       if (inputEvent.getSource() instanceof JComponent) {
86         contextComponent = (JComponent)inputEvent.getSource();
87       }
88     }
89
90     showPopup(context, popup, contextComponent);
91   }
92
93   protected void showPopup(DataContext context, ListPopup popup, JComponent contextComponent) {
94     Component focusedComponent = contextComponent != null ? contextComponent : PlatformDataKeys.CONTEXT_COMPONENT.getData(context);
95     if (focusedComponent != null) {
96       if (popup instanceof PopupFactoryImpl.ActionGroupPopup && focusedComponent instanceof JLabel) {
97         ((PopupFactoryImpl.ActionGroupPopup)popup).showUnderneathOfLabel((JLabel)focusedComponent);
98       } else {
99         popup.showUnderneathOf(focusedComponent);
100       }
101     }
102     else {
103       Rectangle r;
104       int x;
105       int y;
106       focusedComponent = WindowManagerEx.getInstanceEx().getFocusedComponent((Project)null);
107       r = WindowManagerEx.getInstanceEx().getScreenBounds();
108       x = r.x + r.width / 2;
109       y = r.y + r.height / 2;
110       Point point = new Point(x, y);
111       SwingUtilities.convertPointToScreen(point, focusedComponent.getParent());
112
113       popup.showInScreenCoordinates(focusedComponent.getParent(), point);
114     }
115   }
116 }