IDEA-19061 Integrate the Rearranger-plugin into core-IDE

Decorating match condition row to show an index and 'edit' icon
This commit is contained in:
Denis.Zhdanov
2012-11-01 15:01:01 +04:00
parent 49df96a495
commit af9eddfe73
7 changed files with 222 additions and 16 deletions
@@ -56,7 +56,7 @@ public class ArrangementColorsProviderImpl implements ArrangementColorsProvider
@NotNull
@Override
public Color getBorderColor(boolean selected) {
return selected ? myBorderColor : mySelectedBorderColor;
return selected ? mySelectedBorderColor : myBorderColor;
}
@NotNull
@@ -34,7 +34,8 @@ public class ArrangementConstants {
@NonNls public static final String RULE_TREE_PLACE = "Arrangement.RuleTree.Place";
public static final int HORIZONTAL_PADDING = 8;
public static final int HORIZONTAL_GAP = 8;
public static final int HORIZONTAL_GAP = 3;
public static final int VERTICAL_GAP = 5;
public static final boolean LOG_RULE_MODIFICATION = Boolean.parseBoolean(System.getProperty("log.arrangement.rule.modification"));
@@ -0,0 +1,127 @@
/*
* Copyright 2000-2012 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.application.options.codeStyle.arrangement.newui;
import com.intellij.application.options.codeStyle.arrangement.ArrangementConstants;
import com.intellij.application.options.codeStyle.arrangement.node.match.ArrangementMatchConditionComponent;
import com.intellij.openapi.actionSystem.ActionManager;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.Presentation;
import com.intellij.openapi.actionSystem.impl.ActionButton;
import com.intellij.psi.codeStyle.arrangement.model.ArrangementMatchCondition;
import com.intellij.ui.IdeBorderFactory;
import com.intellij.util.ui.GridBag;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseEvent;
/**
* @author Denis Zhdanov
* @since 10/31/12 5:00 PM
*/
public class ArrangementListRowDecorator extends JPanel implements ArrangementMatchConditionComponent {
@NotNull private final ArrangementRuleIndexControl myRowIndexControl;
@NotNull private final ArrangementMatchConditionComponent myDelegate;
@NotNull private final ActionButton myEditButton;
public ArrangementListRowDecorator(@NotNull ArrangementMatchConditionComponent delegate) {
myDelegate = delegate;
AnAction action = ActionManager.getInstance().getAction("Arrangement.Rule.Edit");
Presentation presentation = action.getTemplatePresentation().clone();
Icon editIcon = presentation.getIcon();
Dimension buttonSize = new Dimension(editIcon.getIconWidth(), editIcon.getIconHeight());
myEditButton = new ActionButton(action, presentation, ArrangementConstants.RULE_TREE_PLACE, buttonSize);
myEditButton.setVisible(false);
FontMetrics metrics = getFontMetrics(getFont());
int maxWidth = 0;
for (int i = 0; i <= 99; i++) {
maxWidth = Math.max(metrics.stringWidth(String.valueOf(i)), maxWidth);
}
int height = metrics.getHeight() - metrics.getDescent() - metrics.getLeading();
int diameter = Math.max(maxWidth, height) * 5 / 3;
myRowIndexControl = new ArrangementRuleIndexControl(diameter, height);
setOpaque(false);
init();
}
private void init() {
setLayout(new GridBagLayout());
GridBag constraints = new GridBag().anchor(GridBagConstraints.CENTER)
.insets(0, ArrangementConstants.HORIZONTAL_PADDING, 0, ArrangementConstants.HORIZONTAL_PADDING * 3);
add(myRowIndexControl, constraints);
add(myDelegate.getUiComponent(), new GridBag().fillCellHorizontally().weightx(1).anchor(GridBagConstraints.WEST));
add(myEditButton, new GridBag().anchor(GridBagConstraints.EAST));
setBorder(IdeBorderFactory.createEmptyBorder(ArrangementConstants.VERTICAL_GAP));
}
public void setRowIndex(int row) {
myRowIndexControl.setIndex(row);
}
@NotNull
@Override
public ArrangementMatchCondition getMatchCondition() {
return myDelegate.getMatchCondition();
}
@NotNull
@Override
public JComponent getUiComponent() {
return this;
}
@Nullable
@Override
public Rectangle getScreenBounds() {
// TODO den implement
return null;
}
@Override
public void setScreenBounds(@Nullable Rectangle bounds) {
// TODO den implement
}
@Override
public boolean onCanvasWidthChange(int width) {
// TODO den implement
return false;
}
@Override
public void setSelected(boolean selected) {
// TODO den implement
}
@Nullable
@Override
public Rectangle handleMouseMove(@NotNull MouseEvent event) {
// TODO den implement
return null;
}
@Override
public void handleMouseClick(@NotNull MouseEvent event) {
// TODO den implement
}
}
@@ -18,7 +18,6 @@ package com.intellij.application.options.codeStyle.arrangement.newui;
import com.intellij.application.options.codeStyle.arrangement.ArrangementColorsProvider;
import com.intellij.application.options.codeStyle.arrangement.ArrangementConstants;
import com.intellij.application.options.codeStyle.arrangement.ArrangementNodeDisplayManager;
import com.intellij.application.options.codeStyle.arrangement.node.match.ArrangementMatchConditionComponent;
import com.intellij.application.options.codeStyle.arrangement.node.match.ArrangementMatchNodeComponentFactory;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.psi.codeStyle.arrangement.match.StdArrangementMatchRule;
@@ -41,8 +40,7 @@ public class ArrangementMatchingRulesList extends JBList {
private static final Logger LOG = Logger.getInstance("#" + ArrangementMatchingRulesList.class.getName());
@NotNull private final TIntObjectHashMap<ArrangementMatchConditionComponent> myComponents
= new TIntObjectHashMap<ArrangementMatchConditionComponent>();
@NotNull private final TIntObjectHashMap<ArrangementListRowDecorator> myComponents = new TIntObjectHashMap<ArrangementListRowDecorator>();
@NotNull private final DefaultListModel myModel = new DefaultListModel();
@@ -83,20 +81,16 @@ public class ArrangementMatchingRulesList extends JBList {
return Collections.emptyList();
}
// TODO den remove
@Override
public void paint(Graphics g) {
super.paint(g);
}
private class MyListCellRenderer implements ListCellRenderer {
@Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
ArrangementMatchConditionComponent component = myComponents.get(index);
ArrangementListRowDecorator component = myComponents.get(index);
if (component == null) {
StdArrangementMatchRule rule = (StdArrangementMatchRule)value;
myComponents.put(index, component = myFactory.getComponent(rule.getMatcher().getCondition(), rule, true));
component = new ArrangementListRowDecorator(myFactory.getComponent(rule.getMatcher().getCondition(), rule, true));
myComponents.put(index, component);
}
component.setRowIndex(index + 1);
return component.getUiComponent();
}
}
@@ -0,0 +1,85 @@
/*
* Copyright 2000-2012 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.application.options.codeStyle.arrangement.newui;
import com.intellij.util.ui.UIUtil;
import javax.swing.*;
import java.awt.*;
/**
* @author Denis Zhdanov
* @since 10/31/12 5:04 PM
*/
public class ArrangementRuleIndexControl extends JPanel {
private final int myDiameter;
private final int myHeight;
private int myIndex;
private char[] myChars;
private int myIndexWidth;
public ArrangementRuleIndexControl(int diameter, int height) {
myDiameter = diameter;
myHeight = height;
setOpaque(true);
}
public void setIndex(int index) {
if (index == myIndex) {
return;
}
myIndex = index;
String s = String.valueOf(index);
myChars = s.toCharArray();
myIndexWidth = getFontMetrics(getFont()).charsWidth(myChars, 0, myChars.length);
setPreferredSize(new Dimension(myDiameter, myDiameter));
invalidate();
}
@Override
public Dimension getMinimumSize() {
return getPreferredSize();
}
@Override
public Dimension getMaximumSize() {
return getPreferredSize();
}
@Override
public Dimension getPreferredSize() {
// We use increment here because the circle is drawn using antialiasing, hence, couple of sibling pixels are used.
// the border doesn't fit the control bounds without the increment then.
return new Dimension(myDiameter + 2, myDiameter + 2);
}
@Override
protected void paintComponent(Graphics g) {
if (myChars == null) {
return;
}
g.setColor(UIUtil.getBorderColor());
Rectangle bounds = getBounds();
((Graphics2D)g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.drawOval(0, (bounds.height - myDiameter) / 2, myDiameter, myDiameter);
int y = bounds.height - (bounds.height - myHeight) / 2;
g.drawChars(myChars, 0, myChars.length, (bounds.width - myIndexWidth) / 2, y);
}
}
@@ -140,12 +140,11 @@ public class ArrangementAtomMatchConditionComponent implements ArrangementMatchC
}
};
roundBorderPanel.add(insetsPanel, new GridBag().fillCellHorizontally().anchor(GridBagConstraints.WEST));
roundBorderPanel.add(myCloseButton, new GridBag().anchor(GridBagConstraints.CENTER).weightx(1).insets(VERTICAL_PADDING, 0, 0, 0));
roundBorderPanel.add(myCloseButton, new GridBag().anchor(GridBagConstraints.EAST));
myBorder = IdeBorderFactory.createRoundedBorder(arcSize);
roundBorderPanel.setBorder(myBorder);
roundBorderPanel.setOpaque(false);
myRenderer.setBorder(IdeBorderFactory.createEmptyBorder(VERTICAL_PADDING, 0, 0, 0));
myRenderer.add(roundBorderPanel, constraints);
myRenderer.setOpaque(false);
setSelected(false);
@@ -820,7 +820,7 @@
icon="AllIcons.ToolbarDecorator.Remove"/>
<action id="Arrangement.Rule.Edit"
class="com.intellij.application.options.codeStyle.arrangement.action.EditArrangementRuleAction"
icon="AllIcons.ToolbarDecorator.Mac.Edit"/>
icon="AllIcons.Actions.Edit"/>
<action id="Arrangement.Rule.Move.Up"
class="com.intellij.application.options.codeStyle.arrangement.action.MoveArrangementRuleUpAction"
icon="AllIcons.ToolbarDecorator.MoveUp"/>