package jetbrains.mps.vcs.changesmanager.editor;
/*Generated by MPS */
import jetbrains.mps.nodeEditor.leftHighlighter.AbstractFoldingAreaPainter;
import java.awt.Color;
import jetbrains.mps.vcs.diff.ui.common.ChangeGroupLayout;
import jetbrains.mps.vcs.diff.ui.common.ChangeGroup;
import jetbrains.mps.vcs.diff.ui.common.ChangeGroupMessages;
import org.jetbrains.annotations.NotNull;
import jetbrains.mps.nodeEditor.EditorComponent;
import java.awt.Graphics;
import java.awt.Rectangle;
import jetbrains.mps.internal.collections.runtime.ListSequence;
import jetbrains.mps.vcs.diff.ui.common.Bounds;
import jetbrains.mps.vcs.diff.ui.common.ChangeColors;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.util.List;
import jetbrains.mps.vcs.diff.changes.ModelChange;
import jetbrains.mps.vcs.diff.changes.SetPropertyChange;
import jetbrains.mps.vcs.diff.changes.SetReferenceChange;
import jetbrains.mps.vcs.diff.changes.NodeGroupChange;
import jetbrains.mps.util.NameUtil;
import org.jetbrains.annotations.Nullable;
import java.awt.Point;
import jetbrains.mps.internal.collections.runtime.IWhereFilter;
import jetbrains.mps.internal.collections.runtime.ITranslator2;
import jetbrains.mps.vcs.diff.ui.common.ChangeEditorMessage;
import jetbrains.mps.internal.collections.runtime.IVisitor;
import java.awt.event.MouseEvent;
import java.awt.Cursor;
import jetbrains.mps.openapi.editor.cells.EditorCell;
public class ChangeStripsPainter extends AbstractFoldingAreaPainter {
private static final int AREA_WIDTH = 6;
private static final int ARROW_HEIGHT = 8;
private static final Color AREA_FRAME_COLOR = Color.GRAY;
private EditorHighlighter myEditorHighlighter;
private ChangeGroupLayout myChangeGroupLayout;
private ChangeGroup myGroupUnderMouse;
private PopupPanel myPopupToolbar = null;
private ChangeGroupMessages myGroupMessages;
public ChangeStripsPainter(@NotNull EditorHighlighter editorHighlighter) {
super(editorHighlighter.getLeftEditorHighlighter());
myEditorHighlighter = editorHighlighter;
myChangeGroupLayout = new StripsChangeGroupLayout(myEditorHighlighter);
myGroupMessages = new ChangeGroupMessages(myChangeGroupLayout, true);
myGroupMessages.startMaintaining();
}
@NotNull
@Override
protected EditorComponent getEditorComponent() {
return super.getEditorComponent();
}
@Override
public int getWeight() {
return 0;
}
@Override
protected void paintInLocalCoordinates(Graphics g) {
Rectangle clipBounds = g.getClipBounds();
if (clipBounds.x + clipBounds.width < -AREA_WIDTH - 1 || 0 < clipBounds.x) {
return;
}
for (ChangeGroup changeGroup : ListSequence.fromList(myChangeGroupLayout.getChangeGroups())) {
Bounds bounds = changeGroup.getBounds(true);
int y = (int) bounds.start();
g.setColor(ChangeColors.get(changeGroup.getChangeType()));
if (bounds.length() <= 1) {
Graphics2D g2d = ((Graphics2D) g);
Object oldAntialiasing = g2d.getRenderingHint(RenderingHints.KEY_ANTIALIASING);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
int[] xPoints = new int[]{-AREA_WIDTH, -AREA_WIDTH, -1};
int[] yPoints = new int[]{y, y + ChangeStripsPainter.ARROW_HEIGHT, y + ChangeStripsPainter.ARROW_HEIGHT / 2};
g.fillPolygon(xPoints, yPoints, 3);
g.setColor(AREA_FRAME_COLOR);
g.drawPolygon(xPoints, yPoints, 3);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, oldAntialiasing);
continue;
}
int height = bounds.length();
if (height == 0 || y + height < clipBounds.y) {
continue;
}
if (clipBounds.y + clipBounds.height < y) {
break;
}
g.fillRect(-AREA_WIDTH, y, AREA_WIDTH, height);
g.setColor(AREA_FRAME_COLOR);
g.drawLine(-AREA_WIDTH, y, 0, y);
g.drawLine(-AREA_WIDTH, y + height, 0, y + height);
g.drawLine(-AREA_WIDTH, y, -AREA_WIDTH, y + height);
}
}
@Override
public int getLeftAreaWidth() {
return AREA_WIDTH;
}
@Override
public void relayout() {
myChangeGroupLayout.invalidate();
}
@Override
public String getToolTipText() {
if (myGroupUnderMouse == null) {
return null;
} else {
List<ModelChange> changes = myGroupUnderMouse.getChanges();
if (ListSequence.fromList(changes).count() == 1) {
ModelChange change = ListSequence.fromList(changes).first();
if (change instanceof SetPropertyChange) {
return "Changed " + ((SetPropertyChange) change).getPropertyName();
} else if (change instanceof SetReferenceChange) {
return "Changed " + ((SetReferenceChange) change).getRole() + " reference";
} else if (change instanceof NodeGroupChange) {
return ((NodeGroupChange) change).getDescription(false);
}
}
return NameUtil.formatNumericalString(ListSequence.fromList(changes).count(), "change");
}
}
@Nullable
private ChangeGroup findMessageGroupUnder(@NotNull final Point p) {
double localX = p.getX() - getLeftHighlighter().getFoldingLineX();
if (localX >= -AREA_WIDTH && localX < 0) {
return ListSequence.fromList(myChangeGroupLayout.getChangeGroups()).findFirst(new IWhereFilter<ChangeGroup>() {
public boolean accept(ChangeGroup cg) {
Bounds b = cg.getBounds(true);
return (int) b.start() <= p.getY() && p.getY() <= (int) b.end() || b.length() <= 1 && (int) b.start() - ARROW_HEIGHT / 2 <= p.getY() && p.getY() <= (int) b.end() + ARROW_HEIGHT / 2;
}
});
} else {
return null;
}
}
/*package*/ void setGroupHighlighted(@Nullable ChangeGroup group, final boolean highlighted) {
if (group != null) {
ListSequence.fromList(group.getChanges()).translate(new ITranslator2<ModelChange, ChangeEditorMessage>() {
public Iterable<ChangeEditorMessage> translate(ModelChange ch) {
return myEditorHighlighter.getMessages(ch);
}
}).visitAll(new IVisitor<ChangeEditorMessage>() {
public void visit(ChangeEditorMessage m) {
m.setHighlighted(highlighted);
}
});
}
}
private void setGroupUnderMouse(@Nullable ChangeGroup group) {
if (myGroupUnderMouse == group) {
return;
}
setGroupHighlighted(myGroupUnderMouse, false);
myGroupUnderMouse = group;
setGroupHighlighted(myGroupUnderMouse, true);
if (myPopupToolbar != null) {
setGroupHighlighted(myPopupToolbar.getChangeGroup(), true);
}
myEditorHighlighter.getHighlightManager().repaintAndRebuildEditorMessages();
}
@Override
public void mouseMoved(MouseEvent event) {
ChangeGroup changeGroup = findMessageGroupUnder(event.getPoint());
if (changeGroup != null) {
event.consume();
}
setGroupUnderMouse(changeGroup);
if (changeGroup != null) {
event.getComponent().setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
} else {
event.getComponent().setCursor(null);
}
}
@Override
public void mouseExited(MouseEvent event) {
event.getComponent().setCursor(null);
setGroupUnderMouse(null);
}
@Override
public void mousePressed(MouseEvent event) {
if (event.getID() != MouseEvent.MOUSE_CLICKED) {
return;
}
check_h84zmo_a1a02(myPopupToolbar);
getEditorComponent().requestFocus();
if (event.getButton() == MouseEvent.BUTTON1) {
ChangeGroup changeGroup = findMessageGroupUnder(event.getPoint());
if (changeGroup != null) {
showPopupForGroup(changeGroup, event.getY());
event.consume();
}
}
}
private void showPopupForGroup(@NotNull ChangeGroup changeGroup, int y) {
int foldingLineX = getEditorComponent().getLeftEditorHighlighter().getFoldingLineX();
EditorCell cell = getEditorComponent().findCellWeak(foldingLineX, y);
if (cell != null) {
getEditorComponent().changeSelection(cell);
}
myPopupToolbar = new PopupPanel(this, changeGroup);
myPopupToolbar.show(0, y);
}
/*package*/ void popupClosed() {
myPopupToolbar = null;
}
@Nullable
/*package*/ ChangeGroup getNeighbourChangeGroup(@Nullable EditorCell contextCell, boolean next) {
if (contextCell == null) {
return null;
}
if (next) {
final int bottomY = contextCell.getY() + contextCell.getHeight();
return ListSequence.fromList(myChangeGroupLayout.getChangeGroups()).findFirst(new IWhereFilter<ChangeGroup>() {
public boolean accept(ChangeGroup g) {
return bottomY < (int) g.getBounds(true).start();
}
});
} else {
final int topY = contextCell.getY();
return ListSequence.fromList(myChangeGroupLayout.getChangeGroups()).findLast(new IWhereFilter<ChangeGroup>() {
public boolean accept(ChangeGroup g) {
return topY > (int) g.getBounds(true).end();
}
});
}
}
@Nullable
/*package*/ ChangeGroup getCurrentChangeGroup() {
return check_h84zmo_a0a42(myPopupToolbar);
}
/*package*/ void showPopupForGroup(@Nullable ChangeGroup group) {
check_h84zmo_a0a52(myPopupToolbar);
if (group != null) {
showPopupForGroup(group, (int) group.getBounds(true).start());
}
}
@Override
public void dispose() {
myGroupMessages.dispose();
super.dispose();
}
private static void check_h84zmo_a1a02(PopupPanel checkedDotOperand) {
if (null != checkedDotOperand) {
checkedDotOperand.dispose();
}
}
private static ChangeGroup check_h84zmo_a0a42(PopupPanel checkedDotOperand) {
if (null != checkedDotOperand) {
return checkedDotOperand.getChangeGroup();
}
return null;
}
private static void check_h84zmo_a0a52(PopupPanel checkedDotOperand) {
if (null != checkedDotOperand) {
checkedDotOperand.dispose();
}
}
}