mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
diff: allow to change proportions in three-side viewer
This commit is contained in:
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user