IDEA-175743 Review changes

See the UI spec at https://youtrack.jetbrains.com/issue/IDEA-175743#comment=27-2426968
This commit is contained in:
Rustam Vishnyakov
2017-10-11 12:17:41 +03:00
parent 592e7789a9
commit 164cb1b29d
5 changed files with 210 additions and 222 deletions
@@ -52,4 +52,8 @@ public class FileStatusColorDescriptor {
public void resetToDefault() {
myColor = myDefaultColor;
}
public Color getDefaultColor() {
return myDefaultColor;
}
}
@@ -1,16 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.application.options.colors.fileStatus.FileStatusColorsPanel">
<grid id="27dc6" binding="myTopPanel" layout-manager="GridLayoutManager" row-count="2" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<grid id="27dc6" binding="myTopPanel" layout-manager="GridLayoutManager" row-count="3" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<xy x="20" y="20" width="500" height="400"/>
<xy x="20" y="20" width="1227" height="400"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<scrollpane id="477c9" class="com.intellij.ui.components.JBScrollPane">
<scrollpane id="477c9" class="com.intellij.ui.components.JBScrollPane" binding="myTablePane">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
<grid row="0" column="0" row-span="2" col-span="1" vsize-policy="3" hsize-policy="0" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
@@ -21,16 +21,69 @@
</component>
</children>
</scrollpane>
<vspacer id="3cdea">
<grid id="3a7ad" binding="myColorSettingsPanel" layout-manager="GridBagLayout">
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="1" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="dc198" class="com.intellij.ui.components.JBCheckBox" binding="myFileStatusColorBox">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<gridbag weightx="0.0" weighty="1.0"/>
</constraints>
<properties>
<text value="File status color:"/>
</properties>
</component>
<component id="8ef3e" class="com.intellij.ui.ColorPanel" binding="myColorPanel">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
<gridbag weightx="1.0" weighty="1.0"/>
</constraints>
<properties/>
</component>
<grid id="67522" layout-manager="FlowLayout" hgap="0" vgap="18" flow-align="1">
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
<gridbag weightx="0.0" weighty="0.0"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="46f7e" class="javax.swing.JButton" binding="myRestoreButton">
<constraints/>
<properties>
<horizontalAlignment value="2"/>
<text value="Restore Default"/>
</properties>
</component>
<hspacer id="ca7dd">
<constraints/>
</hspacer>
</children>
</grid>
</children>
</grid>
<vspacer id="ebaa2">
<constraints>
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
<hspacer id="2f870">
<hspacer id="e0ac4">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
<grid row="0" column="2" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
</hspacer>
<component id="8fe29" class="javax.swing.JLabel" binding="myCustomizedLabel">
<constraints>
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="* Customized"/>
</properties>
</component>
</children>
</grid>
</form>
@@ -18,14 +18,37 @@ package com.intellij.application.options.colors.fileStatus;
import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.editor.colors.EditorColorsScheme;
import com.intellij.openapi.vcs.FileStatus;
import com.intellij.ui.ColorPanel;
import com.intellij.ui.JBColor;
import com.intellij.ui.components.JBCheckBox;
import com.intellij.ui.components.JBScrollPane;
import com.intellij.ui.table.JBTable;
import com.intellij.util.ui.JBUI;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class FileStatusColorsPanel {
private static final int TABLE_SIZE = 250; // Defined by UI spec
private JPanel myTopPanel;
private JBTable myFileStatusColorsTable;
private JBCheckBox myFileStatusColorBox;
private JButton myRestoreButton;
private ColorPanel myColorPanel;
private JBScrollPane myTablePane;
private JPanel myColorSettingsPanel;
private JLabel myCustomizedLabel;
private final FileStatusColorsTableModel myModel;
public FileStatusColorsPanel(@NotNull FileStatus[] fileStatuses) {
@@ -34,6 +57,49 @@ public class FileStatusColorsPanel {
myModel);
((FileStatusColorsTable)myFileStatusColorsTable).adjustColumnWidths();
myModel.addTableModelListener(myFileStatusColorsTable);
myFileStatusColorsTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent e) {
updateColorPanel(myModel.getDescriptorAt(myFileStatusColorsTable.getSelectedRow()));
}
});
myRestoreButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
restoreDefault(myFileStatusColorsTable.getSelectedRow());
}
});
myFileStatusColorBox.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
setUseColor(myFileStatusColorsTable.getSelectedRow(), myFileStatusColorBox.isSelected());
}
});
myColorPanel.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
//noinspection ConstantConditions
setColor(myFileStatusColorsTable.getSelectedRow(), myColorPanel.getSelectedColor());
}
});
adjustTableSize();
myColorSettingsPanel.setVisible(false);
myCustomizedLabel.setForeground(JBColor.GRAY);
myCustomizedLabel.setVisible(myModel.containsCustomSettings());
myModel.addTableModelListener(new TableModelListener() {
@Override
public void tableChanged(TableModelEvent e) {
myCustomizedLabel.setVisible(myModel.containsCustomSettings());
}
});
}
private void adjustTableSize() {
Dimension d = myFileStatusColorsTable.getPreferredSize();
d.setSize(JBUI.scale(TABLE_SIZE), d.height);
myTablePane.setMinimumSize(new Dimension(JBUI.scale(TABLE_SIZE),0));
myTablePane.setPreferredSize(d);
myTablePane.setMaximumSize(d);
}
public JPanel getComponent() {
@@ -41,7 +107,7 @@ public class FileStatusColorsPanel {
}
private void createUIComponents() {
myFileStatusColorsTable = new FileStatusColorsTable(getCurrentScheme().getDefaultForeground());
myFileStatusColorsTable = new FileStatusColorsTable();
}
@NotNull
@@ -53,4 +119,45 @@ public class FileStatusColorsPanel {
public FileStatusColorsTableModel getModel() {
return myModel;
}
private void updateColorPanel(@Nullable FileStatusColorDescriptor descriptor) {
if (descriptor == null) {
myColorSettingsPanel.setVisible(false);
}
else {
myColorSettingsPanel.setVisible(true);
myFileStatusColorBox.setSelected(descriptor.getColor() != null);
myRestoreButton.setEnabled(!descriptor.isDefault());
myColorPanel.setSelectedColor(descriptor.getColor());
}
}
private void restoreDefault(int row) {
if (row >= 0) {
myModel.resetToDefault(row);
updateColorPanel(myModel.getDescriptorAt(row));
}
}
private void setUseColor(int row, boolean useColor) {
if (row >= 0) {
FileStatusColorDescriptor descriptor = myModel.getDescriptorAt(row);
if (descriptor != null) {
Color defaultColor = descriptor.getDefaultColor();
Color c = useColor ? defaultColor != null ? defaultColor : UIUtil.getLabelForeground() : null;
getModel().setValueAt(c, row, 1);
updateColorPanel(descriptor);
}
}
}
private void setColor(int row, @NotNull Color color) {
if (row >= 0) {
myModel.setValueAt(color, row, 1);
FileStatusColorDescriptor descriptor = myModel.getDescriptorAt(row);
if (descriptor != null) {
updateColorPanel(descriptor);
}
}
}
}
@@ -15,19 +15,10 @@
*/
package com.intellij.application.options.colors.fileStatus;
import com.intellij.openapi.application.ApplicationBundle;
import com.intellij.openapi.ui.JBMenuItem;
import com.intellij.openapi.ui.JBPopupMenu;
import com.intellij.ui.ClickListener;
import com.intellij.ui.ColorPicker;
import com.intellij.ui.ColorUtil;
import com.intellij.ui.table.JBTable;
import com.intellij.util.ui.EmptyIcon;
import com.intellij.util.ui.JBEmptyBorder;
import com.intellij.util.ui.JBUI;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.table.DefaultTableCellRenderer;
@@ -35,157 +26,42 @@ import javax.swing.table.DefaultTableColumnModel;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import static java.lang.Math.ceil;
public class FileStatusColorsTable extends JBTable {
private JBPopupMenu mySetColorMenu;
private JBMenuItem myResetItem;
private final Color myDefaultColor;
public FileStatusColorsTable(@NotNull Color defaultColor) {
myDefaultColor = defaultColor;
public FileStatusColorsTable() {
setShowGrid(false);
getColumnModel().setColumnSelectionAllowed(false);
setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
setDefaultRenderer(Color.class, new MyColorCellRenderer());
setDefaultRenderer(String.class, new MyStatusCellRenderer());
setDefaultRenderer(Boolean.class, new MyDefaultStatusRenderer());
setTableHeader(null);
registerKeyboardAction(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
setColor(null);
}
}, KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0, false), JComponent.WHEN_FOCUSED);
new ClickListener() {
@Override
public boolean onClick(@NotNull MouseEvent event, int clickCount) {
Point mouseLoc = event.getPoint();
int col = FileStatusColorsTable.this.columnAtPoint(mouseLoc);
return isColorColumn(col) && setColor(mouseLoc);
}
}.installOn(this);
initPopup();
}
private void initPopup() {
mySetColorMenu = new JBPopupMenu();
mySetColorMenu.add(new JBMenuItem(new DropColorAction()));
myResetItem = new JBMenuItem(new ResetToDefaultAction());
mySetColorMenu.add(myResetItem);
mySetColorMenu.add(new JBMenuItem(new ChooseColorAction()));
}
private class ChooseColorAction extends AbstractAction {
public ChooseColorAction() {
super(ApplicationBundle.message("file.status.color.menu.choose.color"));
}
@Override
public void actionPerformed(ActionEvent e) {
editColor();
}
}
private class DropColorAction extends AbstractAction {
public DropColorAction() {
super(ApplicationBundle.message("file.status.color.menu.normal.text"));
}
@Override
public void actionPerformed(ActionEvent e) {
int row = getSelectedRow();
if (row >= 0) {
getModel().setValueAt(null, row, 1);
}
}
}
private class ResetToDefaultAction extends AbstractAction {
public ResetToDefaultAction() {
super(ApplicationBundle.message("file.status.color.menu.reset.to.default"));
}
@Override
public void actionPerformed(ActionEvent e) {
int row = getSelectedRow();
if (row >= 0) {
((FileStatusColorsTableModel)getModel()).resetToDefault(row);
}
}
}
private boolean setColor(@Nullable Point mouseLoc) {
Point location = getPopupLocation(mouseLoc);
if (location != null) {
mySetColorMenu.show(this, location.x, location.y);
myResetItem.setEnabled(isResetAvailable());
mySetColorMenu.pack();
mySetColorMenu.getSelectionModel().setSelectedIndex(0);
return true;
}
return false;
}
private boolean isResetAvailable() {
int row = getSelectedRow();
return row >= 0 && ((FileStatusColorsTableModel)getModel()).isResetAvailable(row);
}
@Nullable
private Point getPopupLocation(@Nullable Point mouseLoc) {
if (mouseLoc != null) {
Point tableLoc = this.getLocation();
tableLoc.translate(mouseLoc.x, mouseLoc.y);
return tableLoc;
}
else {
int row = getSelectedRow();
if (row >= 0) {
Rectangle cellRect = getCellRect(row, getColumn(Color.class), false);
Point p = cellRect.getLocation();
p.translate(0, cellRect.height);
return p;
}
}
return null;
}
private void editColor() {
int row = getSelectedRow();
if (row >= 0) {
int colorColumn = getColumn(Color.class);
Color currentColor = (Color)getModel().getValueAt(row, colorColumn);
Color color = ColorPicker.showDialog(this, ApplicationBundle.message("title.file.status.color"), currentColor, true, null, false);
if (color != null) {
getModel().setValueAt(color, row, colorColumn);
}
}
setRowHeight(JBUI.scale(22));
}
public void adjustColumnWidths() {
for (int col = 0; col < getColumnCount(); col++) {
int rightGap = isColorColumn(col) ? JBUI.size(10, 1).width : 0;
DefaultTableColumnModel colModel = (DefaultTableColumnModel) getColumnModel();
TableColumn column = colModel.getColumn(col);
Class colClass = getColumnClass(col);
int width = 0;
TableCellRenderer renderer;
for (int row = 0; row < getRowCount(); row++) {
renderer = getCellRenderer(row, col);
Component comp = renderer.getTableCellRendererComponent(this, getValueAt(row, col),
false, false, row, col);
width = Math.max(width, comp.getPreferredSize().width);
int rightGap = 0;
if (getColumnClass(col).equals(Boolean.class)) {
width = JBUI.scale(10);
}
else {
rightGap = isColorColumn(col) ? JBUI.size(10, 1).width : 0;
TableCellRenderer renderer;
for (int row = 0; row < getRowCount(); row++) {
renderer = getCellRenderer(row, col);
Component comp = renderer.getTableCellRendererComponent(this, getValueAt(row, col),
false, false, row, col);
width = Math.max(width, comp.getPreferredSize().width);
}
}
width += rightGap;
column.setPreferredWidth(width);
if (isColorColumn(col)) {
if (colClass.equals(Color.class) || colClass.equals(Boolean.class)) {
column.setMinWidth(width);
column.setMaxWidth(width);
}
@@ -196,41 +72,6 @@ public class FileStatusColorsTable extends JBTable {
return getModel().getColumnClass(col).equals(Color.class);
}
private int getColumn(@NotNull Class columnClass) {
for (int i = 0; i < getModel().getColumnCount(); i ++) {
if (getModel().getColumnClass(i).equals(columnClass)) return i;
}
return -1;
}
private class MyColorCellRenderer implements TableCellRenderer {
public static final int RIGHT_GAP = 10;
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
JLabel colorLabel = new JLabel();
Color c = getDisplayColor(value);
colorLabel.setBorder(new JBEmptyBorder(0, RIGHT_GAP, 0, 0));
colorLabel.setIcon(getIcon(c));
//noinspection StringToUpperCaseOrToLowerCaseWithoutLocale
colorLabel.setText(value != null ? ColorUtil.toHex(c).toUpperCase() : ApplicationBundle.message("file.status.color.none"));
if (isSelected) {
colorLabel.setOpaque(true);
colorLabel.setForeground(UIUtil.getTableSelectionForeground());
colorLabel.setBackground(UIUtil.getTableSelectionBackground());
}
return colorLabel;
}
private Icon getIcon(@NotNull Color color) {
return JBUI.scale(new MyColorIcon(color));
}
}
private Color getDisplayColor(@Nullable Object value) {
return value instanceof Color ? (Color)value : myDefaultColor;
}
private class MyStatusCellRenderer extends DefaultTableCellRenderer {
private final JLabel myLabel = new JLabel();
@@ -269,37 +110,11 @@ public class FileStatusColorsTable extends JBTable {
if (value instanceof Boolean) {
myLabel.setForeground(isSelected ? UIUtil.getTableSelectionForeground() : myLabelColor);
myLabel.setBackground(UIUtil.getTableBackground(isSelected));
myLabel.setText((Boolean)value ? "(default)" : "");
myLabel.setText((Boolean)value ? "" : "*");
myLabel.setHorizontalAlignment(SwingConstants.CENTER);
return myLabel;
}
return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
}
}
private static class MyColorIcon extends EmptyIcon {
public static final int COLOR_HEIGHT = 14;
public static final int ICON_HEIGHT = 16;
public static final int ICON_WIDTH = 32;
private Color myColor;
public MyColorIcon(@NotNull Color color) {
//noinspection deprecation
super(ICON_WIDTH, ICON_HEIGHT);
myColor = color;
}
@Override
public void paintIcon(final Component component, final Graphics g, final int i, final int j) {
final int iconHeight = getIconHeight();
final int iconWidth = getIconWidth();
g.setColor(myColor);
final int size = (int)ceil(scaleVal(COLOR_HEIGHT));
final int y = j + (iconHeight - size) / 2;
g.fillRect(i, y, iconWidth, size);
}
}
}
@@ -37,13 +37,11 @@ public class FileStatusColorsTableModel extends AbstractTableModel {
private List<FileStatusColorDescriptor> myDescriptors;
private final static ColumnInfo[] COLUMNS_INFO = {
new ColumnInfo(
String.class, ApplicationBundle.message("file.status.colors.header.status"), descriptor -> descriptor.getStatus().getText()),
new ColumnInfo(
Color.class, ApplicationBundle.message("file.status.colors.header.color"), descriptor -> descriptor.getColor()),
new ColumnInfo(
Boolean.class, "", descriptor -> descriptor.isDefault()
)
),
new ColumnInfo(
String.class, ApplicationBundle.message("file.status.colors.header.status"), descriptor -> descriptor.getStatus().getText())
};
private static class ColumnInfo {
@@ -112,10 +110,6 @@ public class FileStatusColorsTableModel extends AbstractTableModel {
fireTableCellUpdated(rowIndex, 1);
}
boolean isResetAvailable(int rowIndex) {
return !myDescriptors.get(rowIndex).isDefault();
}
@Nullable
FileStatusColorDescriptor getDescriptorByName(String statusName) {
for (FileStatusColorDescriptor descriptor : myDescriptors) {
@@ -151,4 +145,19 @@ public class FileStatusColorsTableModel extends AbstractTableModel {
((AbstractColorsScheme)myScheme).setSaveNeeded(true);
}
}
@Nullable
public FileStatusColorDescriptor getDescriptorAt(int index) {
if (index >= 0 && index < myDescriptors.size()) {
return myDescriptors.get(index);
}
return null;
}
public boolean containsCustomSettings() {
for (FileStatusColorDescriptor descriptor : myDescriptors) {
if (!descriptor.isDefault()) return true;
}
return false;
}
}