diff: allow to change proportions in three-side viewer

This commit is contained in:
Aleksey Pivovarov
2016-03-03 18:50:51 +03:00
parent 4dee50be5f
commit cbebfe1c73
@@ -17,27 +17,39 @@ package com.intellij.diff.tools.util;
import com.intellij.diff.tools.util.DiffSplitter.Painter;
import com.intellij.diff.util.Side;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.icons.AllIcons;
import org.jetbrains.annotations.CalledInAwt;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.util.List;
public class ThreeDiffSplitter extends JPanel {
private static final int DIVIDER_WIDTH = 30;
@NotNull private final List<Divider> myDividers;
@NotNull private final List<? extends JComponent> myContents;
@NotNull private final Divider myDivider1;
@NotNull private final Divider myDivider2;
private float myProportion1; // first size divided by (first + second + third)
private float myProportion2; // third size divided by (first + second + third)
public ThreeDiffSplitter(@NotNull List<? extends JComponent> components) {
myDividers = ContainerUtil.list(new Divider(), new Divider());
assert components.size() == 3;
myContents = components;
myDivider1 = new Divider(Side.LEFT);
myDivider2 = new Divider(Side.RIGHT);
addAll(myContents);
addAll(myDividers);
add(myDivider1);
add(myDivider2);
for (JComponent content : myContents) {
add(content);
}
resetProportions();
}
@CalledInAwt
@@ -56,32 +68,44 @@ public class ThreeDiffSplitter extends JPanel {
@NotNull
private Divider getDivider(@NotNull Side side) {
return myDividers.get(side.getIndex());
return side.select(myDivider1, myDivider2);
}
private void addAll(@NotNull List<? extends JComponent> components) {
for (JComponent component : components) {
add(component, -1);
}
private void resetProportions() {
myProportion1 = myProportion2 = 1f / 3;
}
private void setProportion(float proportion, @NotNull Side side) {
proportion = Math.min(1f, Math.max(0f, proportion));
float otherProportion = side.select(myProportion2, myProportion1);
otherProportion = Math.min(otherProportion, 1f - proportion);
myProportion1 = side.select(proportion, otherProportion);
myProportion2 = side.select(otherProportion, proportion);
}
@Override
public void doLayout() {
int width = getWidth();
int height = getHeight();
int panelWidth = (width - DIVIDER_WIDTH * 2) / 3;
int dividersTotalWidth = DIVIDER_WIDTH * 2;
int contentsTotalWidth = Math.max(width - dividersTotalWidth, 0);
JComponent[] components = new JComponent[]{myContents.get(0), myDivider1, myContents.get(1), myDivider2, myContents.get(2)};
int[] contentWidths = new int[5];
contentWidths[1] = DIVIDER_WIDTH; // divider1
contentWidths[3] = DIVIDER_WIDTH; // divider2
contentWidths[0] = (int)(contentsTotalWidth * myProportion1); // content1
contentWidths[4] = (int)(contentsTotalWidth * myProportion2); // content3
contentWidths[2] = Math.max(contentsTotalWidth - contentWidths[0] - contentWidths[4], 0); // content2
int x = 0;
for (int i = 0; i < myContents.size(); i++) {
JComponent component = myContents.get(i);
component.setBounds(x, 0, panelWidth, height);
for (int i = 0; i < 5; i++) {
JComponent component = components[i];
component.setBounds(x, 0, contentWidths[i], height);
component.validate();
x += panelWidth;
if (i < myDividers.size()) {
JComponent divider = myDividers.get(i);
divider.setBounds(x, 0, DIVIDER_WIDTH, height);
divider.validate();
x += DIVIDER_WIDTH;
}
x += contentWidths[i];
}
}
@@ -109,12 +133,21 @@ public class ThreeDiffSplitter extends JPanel {
return new Dimension(width, height);
}
private static class Divider extends JComponent {
private class Divider extends JPanel {
@NotNull private final Side mySide;
@Nullable private Painter myPainter;
public Divider(@NotNull Side side) {
super(new GridBagLayout());
mySide = side;
enableEvents(MouseEvent.MOUSE_EVENT_MASK | MouseEvent.MOUSE_MOTION_EVENT_MASK);
setCursor(Cursor.getPredefinedCursor(Cursor.W_RESIZE_CURSOR));
add(new JLabel(AllIcons.General.SplitGlueH), new GridBagConstraints());
}
@Override
public void paint(Graphics g) {
super.paint(g);
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (myPainter != null) myPainter.paint(g, this);
}
@@ -122,5 +155,32 @@ public class ThreeDiffSplitter extends JPanel {
public void setPainter(@Nullable Painter painter) {
myPainter = painter;
}
@Override
protected void processMouseMotionEvent(MouseEvent e) {
super.processMouseMotionEvent(e);
if (e.getID() == MouseEvent.MOUSE_DRAGGED) {
int totalWidth = ThreeDiffSplitter.this.getWidth();
if (totalWidth > 0) {
Point point = SwingUtilities.convertPoint(this, e.getPoint(), ThreeDiffSplitter.this);
float proportion = (float)mySide.select(point.x, totalWidth - point.x) / (float)totalWidth;
setProportion(proportion, mySide);
revalidate();
repaint();
}
}
}
@Override
protected void processMouseEvent(MouseEvent e) {
super.processMouseEvent(e);
if (e.getID() == MouseEvent.MOUSE_CLICKED && e.getClickCount() == 2) {
resetProportions();
revalidate();
repaint();
}
}
}
}