Possibility to configure terminal emulator.
[instantlauncher.git] / src / main / java / eu / svjatoslav / instantlauncher / menu / Menu.java
1 package eu.svjatoslav.instantlauncher.menu;
2
3 import eu.svjatoslav.commons.gui.dialog.ExceptionDialog;
4 import eu.svjatoslav.instantlauncher.Utils;
5
6 import javax.swing.*;
7 import javax.swing.border.EmptyBorder;
8 import java.awt.*;
9 import java.awt.event.MouseEvent;
10 import java.awt.event.MouseListener;
11 import java.io.File;
12 import java.util.Arrays;
13 import java.util.HashSet;
14 import java.util.Set;
15
16 class Menu {
17
18     public static final Dimension SIZE_MENU_PANEL = new Dimension(210, 900);
19     private static final Color BUTTON_BG_DIRECTORY = new Color(0, 0, 60);
20
21     private static final Color BUTTON_BG_DIRECTORY_SELECTED = new Color(0, 0, 100);
22     private static final Color BUTTON_BG_LINK = new Color(60, 60, 0);
23
24     private static final Color BUTTON_BG_LINK_SELECTED = new Color(100, 100, 0);
25     private static final Color BUTTON_BG_EXECUTABLE_FILE = new Color(60, 0, 0);
26
27     private static final Color BUTTON_BG_EXECUTABLE_FILE_SELECTED = new Color(100, 0, 0);
28     private static final Color BUTTON_BG_NONEXECUTABLE_FILE = new Color(0, 60, 0);
29
30     private static final Color BUTTON_BG_NONEXECUTABLE_FILE_SELECTED = new Color(0, 100, 0);
31     private static final Dimension SIZE_BUTTON = new Dimension(200, 30);
32     private final Set<MenuListener> menuListeners = new HashSet<>();
33     private JPanel menuPanel;
34     private JButton selectedButton;
35     private File selectedFile;
36
37     public Menu(final File directory) {
38         buildContentPanel(directory);
39     }
40
41     /**
42      * <pre>
43      * Assign specific colors to:
44      *    Directory
45      *    Executable file
46      *    Non executable file
47      * </pre>
48      */
49     private static Color getFileColor(final File file, final boolean selected) {
50         if (file.isDirectory())
51             if (selected)
52                 return BUTTON_BG_DIRECTORY_SELECTED;
53             else
54                 return BUTTON_BG_DIRECTORY;
55
56         if (file.isFile())
57             if (file.canExecute()) {
58                 if (selected)
59                     return BUTTON_BG_EXECUTABLE_FILE_SELECTED;
60                 else
61                     return BUTTON_BG_EXECUTABLE_FILE;
62             } else if (selected)
63                 return BUTTON_BG_NONEXECUTABLE_FILE_SELECTED;
64             else
65                 return BUTTON_BG_NONEXECUTABLE_FILE;
66
67         if (selected)
68             return BUTTON_BG_LINK_SELECTED;
69         else
70             return BUTTON_BG_LINK;
71     }
72
73     public void addMenuListener(final MenuListener menuListener) {
74         menuListeners.add(menuListener);
75     }
76
77     private JButton buildButton(final File file) {
78         JButton button;
79         if (file.isDirectory())
80             button = new JButton("[ " + file.getName() + " ]");
81         else
82             button = new JButton(file.getName());
83
84         button.setBackground(getFileColor(file, false));
85         button.setForeground(new Color(255, 255, 255));
86
87         button.setBorder(new EmptyBorder(5, 10, 5, 10));
88
89         final Menu.ButtonMouseListener mouseListener = new ButtonMouseListener(button, this, file);
90         button.addMouseListener(mouseListener);
91
92         button.setHorizontalTextPosition(SwingConstants.CENTER);
93
94         // set button size
95         Utils.setComponentSize(button, SIZE_BUTTON);
96
97         return button;
98     }
99
100     private void buildContentPanel(final File directory) {
101         menuPanel = new JPanel();
102
103         Utils.setComponentSize(menuPanel, SIZE_MENU_PANEL);
104
105         final BoxLayout layout = new BoxLayout(menuPanel, BoxLayout.Y_AXIS);
106         menuPanel.setLayout(layout);
107         menuPanel.setBackground(Color.BLACK);
108
109         final File[] listFiles = directory.listFiles();
110
111         // Sort files by name
112         Arrays.sort(listFiles, (f1, f2) -> {
113
114             // directories come before files
115             if (f1.isFile() && f2.isDirectory())
116                 return 1;
117             if (f2.isFile() && f1.isDirectory())
118                 return -1;
119
120             // order by file name
121             return f1.getName().toUpperCase().compareTo(f2.getName().toUpperCase());
122         });
123
124         // add files to the panel
125         for (final File file : listFiles)
126             // ignore hidden files
127             if (!file.getName().startsWith(".")) {
128                 menuPanel.add(Box.createVerticalStrut(10));
129                 menuPanel.add(buildButton(file));
130             }
131     }
132
133     public JPanel getMenuPanel() {
134         return menuPanel;
135     }
136
137     private JButton getSelectedButton() {
138         return selectedButton;
139     }
140
141     private File getSelectedFile() {
142         return selectedFile;
143     }
144
145     private void menuItemHighlighted(final File chosenFile) {
146         for (final MenuListener menuListener : menuListeners)
147             menuListener.menuItemHighlighted(this, chosenFile);
148     }
149
150     private void menuItemSelected(final File chosenFile) {
151         for (final MenuListener menuListener : menuListeners)
152             menuListener.menuItemSelected(chosenFile);
153     }
154
155     private void menuItemSelectedAlternative(final File chosenFile) {
156         for (final MenuListener menuListener : menuListeners)
157             menuListener.menuItemSelectedAlternative(chosenFile);
158     }
159
160     private void menuItemSelectedAlternative2(final File chosenFile) {
161         for (final MenuListener menuListener : menuListeners)
162             menuListener.menuItemSelectedAlternative2(chosenFile);
163     }
164
165     private void setSelected(final JButton selectedButton, final File selectedFile) {
166         this.selectedButton = selectedButton;
167         this.selectedFile = selectedFile;
168     }
169
170     public static class ButtonMouseListener implements MouseListener {
171
172         final JButton parentButton;
173         final Menu parentMenu;
174         final File file;
175
176         public ButtonMouseListener(final JButton button, final Menu parentMenu, final File file) {
177             parentButton = button;
178             this.parentMenu = parentMenu;
179             this.file = file;
180         }
181
182         @Override
183         public void mouseClicked(final MouseEvent e) {
184             try {
185
186                 if (e.getButton() == 1) // left mouse click
187                     parentMenu.menuItemSelected(file);
188                 if (e.getButton() == 2) // middle mouse click
189                     parentMenu.menuItemSelectedAlternative2(file);
190                 if (e.getButton() == 3) //right mouse click
191                     parentMenu.menuItemSelectedAlternative(file);
192             } catch (final Exception ex) {
193                 new ExceptionDialog(ex);
194             }
195         }
196
197         @Override
198         public void mouseEntered(final MouseEvent e) {
199             try {
200                 if (parentButton != parentMenu.getSelectedButton()) {
201
202                     if (parentMenu.getSelectedButton() != null)
203                         parentMenu.getSelectedButton().setBackground(getFileColor(parentMenu.getSelectedFile(), false));
204
205                     parentMenu.setSelected(parentButton, file);
206                     parentButton.setBackground(getFileColor(file, true));
207
208                     parentMenu.menuItemHighlighted(file);
209                 }
210             } catch (final Exception ex) {
211                 new ExceptionDialog(ex);
212             }
213         }
214
215         @Override
216         public void mouseExited(final MouseEvent e) {
217         }
218
219         @Override
220         public void mousePressed(final MouseEvent e) {
221         }
222
223         @Override
224         public void mouseReleased(final MouseEvent e) {
225         }
226
227     }
228
229 }