mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
thin tool window splitters
This commit is contained in:
@@ -15,14 +15,20 @@
|
||||
*/
|
||||
package com.intellij.openapi.ui;
|
||||
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.IconLoader;
|
||||
import com.intellij.openapi.wm.IdeGlassPane;
|
||||
import com.intellij.openapi.wm.IdeGlassPaneUtil;
|
||||
import com.intellij.ui.UIBundle;
|
||||
import com.intellij.util.ui.update.LazyUiDisposable;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.*;
|
||||
|
||||
/**
|
||||
* @author Vladimir Kondratyev
|
||||
@@ -58,6 +64,7 @@ public class ThreeComponentsSplitter extends JPanel {
|
||||
private int myLastSize = 10;
|
||||
|
||||
private boolean myShowDividerControls;
|
||||
private int myDividerZone;
|
||||
|
||||
|
||||
/**
|
||||
@@ -85,6 +92,10 @@ public class ThreeComponentsSplitter extends JPanel {
|
||||
setOrientation(myVerticalSplit);
|
||||
}
|
||||
|
||||
public void setDividerMouseZoneSize(int size) {
|
||||
myDividerZone = size;
|
||||
}
|
||||
|
||||
public boolean isHonorMinimumSize() {
|
||||
return myHonorMinimumSize;
|
||||
}
|
||||
@@ -262,7 +273,7 @@ public class ThreeComponentsSplitter extends JPanel {
|
||||
}
|
||||
|
||||
public void setDividerWidth(int width) {
|
||||
if (width <= 0) {
|
||||
if (width < 0) {
|
||||
throw new IllegalArgumentException("Wrong divider width: " + width);
|
||||
}
|
||||
if (myDividerWidth != width) {
|
||||
@@ -382,17 +393,79 @@ public class ThreeComponentsSplitter extends JPanel {
|
||||
return lastVisible() ? myLastSize : 0;
|
||||
}
|
||||
|
||||
protected class Divider extends JPanel {
|
||||
protected class Divider extends JPanel implements Disposable {
|
||||
protected boolean myDragging;
|
||||
protected Point myPoint;
|
||||
private final boolean myIsFirst;
|
||||
|
||||
private MouseAdapter myListener = new MouseAdapter() {
|
||||
@Override
|
||||
public void mousePressed(MouseEvent e) {
|
||||
MouseEvent event = SwingUtilities.convertMouseEvent(e.getComponent(), e, Divider.this);
|
||||
processMouseEvent(event);
|
||||
if (event.isConsumed()) {
|
||||
e.consume();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseReleased(MouseEvent e) {
|
||||
MouseEvent event = SwingUtilities.convertMouseEvent(e.getComponent(), e, Divider.this);
|
||||
processMouseEvent(event);
|
||||
if (event.isConsumed()) {
|
||||
e.consume();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseDragged(MouseEvent e) {
|
||||
MouseEvent event = SwingUtilities.convertMouseEvent(e.getComponent(), e, Divider.this);
|
||||
processMouseMotionEvent(event);
|
||||
if (event.isConsumed()) {
|
||||
e.consume();
|
||||
}
|
||||
}
|
||||
};
|
||||
private boolean myWasPressedOnMe;
|
||||
|
||||
public Divider(boolean isFirst) {
|
||||
super(new GridBagLayout());
|
||||
setFocusable(false);
|
||||
enableEvents(MouseEvent.MOUSE_EVENT_MASK | MouseEvent.MOUSE_MOTION_EVENT_MASK);
|
||||
myIsFirst = isFirst;
|
||||
setOrientation(myVerticalSplit);
|
||||
|
||||
new LazyUiDisposable<Divider>(null, this, this) {
|
||||
@Override
|
||||
protected void initialize(@NotNull Disposable parent, @NotNull Divider child, @Nullable Project project) {
|
||||
init();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private boolean isInside(Point p) {
|
||||
if (myVerticalSplit) {
|
||||
if (getHeight() > 0) {
|
||||
return p.y >= 0 && p.y < getHeight();
|
||||
} else {
|
||||
return p.y >= -myDividerZone / 2 && p.y < myDividerZone / 2;
|
||||
}
|
||||
} else {
|
||||
if (getWidth() > 0) {
|
||||
return p.x >= 0 && p.x < getWidth();
|
||||
} else {
|
||||
return p.x >= -myDividerZone / 2 && p.x < myDividerZone / 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void init() {
|
||||
IdeGlassPane gp = IdeGlassPaneUtil.find(this);
|
||||
gp.addMouseMotionPreprocessor(myListener, this);
|
||||
gp.addMousePreprocessor(myListener, this);
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
}
|
||||
|
||||
private void setOrientation(boolean isVerticalSplit) {
|
||||
@@ -485,13 +558,13 @@ public class ThreeComponentsSplitter extends JPanel {
|
||||
|
||||
protected void processMouseMotionEvent(MouseEvent e) {
|
||||
super.processMouseMotionEvent(e);
|
||||
if (MouseEvent.MOUSE_DRAGGED == e.getID()) {
|
||||
if (MouseEvent.MOUSE_DRAGGED == e.getID() && myWasPressedOnMe) {
|
||||
myDragging = true;
|
||||
setCursor(getOrientation() ? Cursor.getPredefinedCursor(Cursor.S_RESIZE_CURSOR) : Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR));
|
||||
myPoint = SwingUtilities.convertPoint(this, e.getPoint(), ThreeComponentsSplitter.this);
|
||||
float proportion;
|
||||
if (getOrientation()) {
|
||||
if (getHeight() > 0) {
|
||||
if (getHeight() > 0 || myDividerZone > 0) {
|
||||
if (myIsFirst) {
|
||||
setFirstSize(Math.max(getMinSize(myFirstComponent), myPoint.y));
|
||||
}
|
||||
@@ -501,7 +574,7 @@ public class ThreeComponentsSplitter extends JPanel {
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (getWidth() > 0) {
|
||||
if (getWidth() > 0 || myDividerZone > 0) {
|
||||
if (myIsFirst) {
|
||||
setFirstSize(Math.max(getMinSize(myFirstComponent), myPoint.x));
|
||||
}
|
||||
@@ -512,6 +585,10 @@ public class ThreeComponentsSplitter extends JPanel {
|
||||
}
|
||||
ThreeComponentsSplitter.this.doLayout();
|
||||
}
|
||||
|
||||
if (myWasPressedOnMe) {
|
||||
e.consume();
|
||||
}
|
||||
}
|
||||
|
||||
private int getMinSize(JComponent component) {
|
||||
@@ -545,11 +622,21 @@ public class ThreeComponentsSplitter extends JPanel {
|
||||
}
|
||||
case MouseEvent.MOUSE_PRESSED:
|
||||
{
|
||||
setCursor(getOrientation() ? Cursor.getPredefinedCursor(9) : Cursor.getPredefinedCursor(11));
|
||||
if (isInside(e.getPoint())) {
|
||||
myWasPressedOnMe = true;
|
||||
setCursor(getOrientation() ? Cursor.getPredefinedCursor(9) : Cursor.getPredefinedCursor(11));
|
||||
e.consume();
|
||||
} else {
|
||||
myWasPressedOnMe = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MouseEvent.MOUSE_RELEASED:
|
||||
{
|
||||
if (myWasPressedOnMe) {
|
||||
e.consume();
|
||||
}
|
||||
myWasPressedOnMe = false;
|
||||
myDragging = false;
|
||||
myPoint = null;
|
||||
break;
|
||||
|
||||
@@ -16,7 +16,9 @@
|
||||
package com.intellij.util.ui.update;
|
||||
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.actionSystem.DataContext;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.AsyncResult;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.actionSystem.PlatformDataKeys;
|
||||
import com.intellij.openapi.actionSystem.DataKey;
|
||||
@@ -58,10 +60,18 @@ public abstract class LazyUiDisposable<T extends Disposable> implements Activata
|
||||
if (myWasEverShown) return;
|
||||
|
||||
try {
|
||||
final Disposable parent = findParentDisposable();
|
||||
initialize(parent, myChild, findProject());
|
||||
Disposer.register(parent, myChild);
|
||||
} finally {
|
||||
findParentDisposable().doWhenDone(new AsyncResult.Handler<Disposable>() {
|
||||
public void run(Disposable parent) {
|
||||
Project project = null;
|
||||
if (ApplicationManager.getApplication() != null) {
|
||||
project = PlatformDataKeys.PROJECT.getData(DataManager.getInstance().getDataContext());
|
||||
}
|
||||
initialize(parent, myChild, project);
|
||||
Disposer.register(parent, myChild);
|
||||
}
|
||||
});
|
||||
}
|
||||
finally {
|
||||
myWasEverShown = true;
|
||||
}
|
||||
}
|
||||
@@ -72,26 +82,32 @@ public abstract class LazyUiDisposable<T extends Disposable> implements Activata
|
||||
protected abstract void initialize(@NotNull Disposable parent, @NotNull T child, @Nullable Project project);
|
||||
|
||||
@NotNull
|
||||
private Disposable findParentDisposable() {
|
||||
final Disposable parent = findObject(myParent, PlatformDataKeys.UI_DISPOSABLE);
|
||||
return parent != null ? parent : Disposer.get("ui");
|
||||
private AsyncResult<Disposable> findParentDisposable() {
|
||||
return findDisposable(myParent, PlatformDataKeys.UI_DISPOSABLE);
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
private Project findProject() {
|
||||
return (Project) findObject(myProject, PlatformDataKeys.PROJECT);
|
||||
}
|
||||
|
||||
private Disposable findObject(Disposable defaultValue, DataKey<? extends Disposable> key) {
|
||||
private static AsyncResult<Disposable> findDisposable(Disposable defaultValue, final DataKey<? extends Disposable> key) {
|
||||
if (defaultValue == null) {
|
||||
if (ApplicationManager.getApplication() != null) {
|
||||
return key.getData(DataManager.getInstance().getDataContext());
|
||||
} else {
|
||||
final AsyncResult<Disposable> result = new AsyncResult<Disposable>();
|
||||
DataManager.getInstance().getDataContextFromFocus().doWhenDone(new AsyncResult.Handler<DataContext>() {
|
||||
public void run(DataContext context) {
|
||||
Disposable disposable = key.getData(context);
|
||||
if (disposable == null) {
|
||||
disposable = Disposer.get("ui");
|
||||
}
|
||||
result.setDone(disposable);
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
return defaultValue;
|
||||
}
|
||||
else {
|
||||
return new AsyncResult.Done<Disposable>(defaultValue);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+13
-25
@@ -147,6 +147,18 @@ final class EditorTabbedContainer implements Disposable, CloseAction.CloseTarget
|
||||
|
||||
UISettings uiSettings = UISettings.getInstance();
|
||||
|
||||
List<String> topIds = mgr.getIdsOn(ToolWindowAnchor.TOP);
|
||||
List<String> bottom = mgr.getIdsOn(ToolWindowAnchor.BOTTOM);
|
||||
List<String> rightIds = mgr.getIdsOn(ToolWindowAnchor.RIGHT);
|
||||
List<String> leftIds = mgr.getIdsOn(ToolWindowAnchor.LEFT);
|
||||
|
||||
if (!uiSettings.HIDE_TOOL_STRIPES) {
|
||||
border.top = topIds.size() > 0 ? 1: 0;
|
||||
border.bottom = bottom.size() > 0 ? 1: 0;
|
||||
border.left = leftIds.size() > 0 ? 1: 0;
|
||||
border.right = rightIds.size() > 0 ? 1: 0;
|
||||
}
|
||||
|
||||
for (String each : ids) {
|
||||
ToolWindow eachWnd = mgr.getToolWindow(each);
|
||||
if (!eachWnd.isAvailable()) continue;
|
||||
@@ -160,35 +172,11 @@ final class EditorTabbedContainer implements Disposable, CloseAction.CloseTarget
|
||||
} else if (eachAnchor == ToolWindowAnchor.LEFT) {
|
||||
border.left = 1;
|
||||
} else if (eachAnchor == ToolWindowAnchor.RIGHT) {
|
||||
border.right = 1;
|
||||
border.right = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!uiSettings.HIDE_TOOL_STRIPES) {
|
||||
if (mgr.getIdsOn(ToolWindowAnchor.TOP).size() > 0) {
|
||||
border.top = 1;
|
||||
}
|
||||
|
||||
if (mgr.getIdsOn(ToolWindowAnchor.BOTTOM).size() > 0) {
|
||||
border.bottom = 1;
|
||||
}
|
||||
|
||||
if (mgr.getIdsOn(ToolWindowAnchor.LEFT).size() > 0) {
|
||||
border.left = 1;
|
||||
}
|
||||
|
||||
if (mgr.getIdsOn(ToolWindowAnchor.RIGHT).size() > 0) {
|
||||
border.right = 1;
|
||||
}
|
||||
|
||||
if (!uiSettings.SHOW_STATUS_BAR && !uiSettings.HIDE_TOOL_STRIPES) {
|
||||
border.bottom = 1;
|
||||
}
|
||||
}
|
||||
|
||||
myTabs.getComponent().setBorder(new EmptyBorder(1, 0, 0, 0));
|
||||
|
||||
myTabs.getPresentation().setPaintBorder(border.top, border.left, border.right, border.bottom).setTabSidePaintBorder(5);
|
||||
}
|
||||
|
||||
|
||||
@@ -46,12 +46,14 @@ import org.jetbrains.annotations.NonNls;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.Border;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
import javax.swing.event.EventListenerList;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Eugene Belyaev
|
||||
@@ -429,6 +431,7 @@ public final class InternalDecorator extends JPanel implements Queryable, TypeSa
|
||||
|
||||
contentPane.add(inner, BorderLayout.CENTER);
|
||||
add(contentPane, BorderLayout.CENTER);
|
||||
setBorder(new EmptyBorder(0, 0, 0, 0));
|
||||
|
||||
// Add listeners
|
||||
registerKeyboardAction(new ActionListener() {
|
||||
@@ -448,21 +451,83 @@ public final class InternalDecorator extends JPanel implements Queryable, TypeSa
|
||||
|
||||
public void paintBorder(final Component c, final Graphics g, final int x, final int y, final int width, final int height) {
|
||||
g.setColor(UIUtil.getBorderInactiveColor());
|
||||
UIUtil.drawLine(g, x, y, x, y + height - 2);
|
||||
UIUtil.drawLine(g, x + width - 1, y, x + width - 1, y + height - 2);
|
||||
|
||||
if (hasBottomLine()) {
|
||||
UIUtil.drawLine(g, x + 1, y + height - 1, x + width - 2, y + height - 1);
|
||||
Insets insets = getBorderInsets(c);
|
||||
|
||||
if (insets.left > 0) {
|
||||
UIUtil.drawLine(g, x, y, x, y + height - 2);
|
||||
}
|
||||
|
||||
if (insets.right > 0) {
|
||||
UIUtil.drawLine(g, x + width - 1, y, x + width - 1, y + height - 2);
|
||||
}
|
||||
|
||||
if (insets.bottom > 0) {
|
||||
UIUtil.drawLine(g, x + 1, y + height - 1, x + width - 2, y + height - 1);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hasBottomLine() {
|
||||
return (myWindow.getAnchor() == ToolWindowAnchor.BOTTOM || myWindow.getAnchor() == ToolWindowAnchor.LEFT || myWindow.getAnchor() == ToolWindowAnchor.RIGHT)
|
||||
&& !UISettings.getInstance().HIDE_TOOL_STRIPES && UISettings.getInstance().SHOW_STATUS_BAR;
|
||||
&& !UISettings.getInstance().HIDE_TOOL_STRIPES && UISettings.getInstance().SHOW_STATUS_BAR || (myWindow.getAnchor() == ToolWindowAnchor.TOP);
|
||||
}
|
||||
|
||||
public Insets getBorderInsets(final Component c) {
|
||||
return new Insets(0, 1, hasBottomLine() ? 1 : 0, 1);
|
||||
UISettings settings = UISettings.getInstance();
|
||||
|
||||
ToolWindowManagerImpl mgr = ((ToolWindowImpl)myWindow).getToolWindowManager();
|
||||
|
||||
List<String> topIds = mgr.getIdsOn(ToolWindowAnchor.TOP);
|
||||
boolean topButtons = !settings.HIDE_TOOL_STRIPES && topIds.size() > 0;
|
||||
boolean windowAtTop = hasDockedVisible(mgr, topIds);
|
||||
|
||||
List<String> bottomIds = mgr.getIdsOn(ToolWindowAnchor.BOTTOM);
|
||||
boolean bottomButtons = !settings.HIDE_TOOL_STRIPES && bottomIds.size() > 0;
|
||||
boolean windowAtBottom = hasDockedVisible(mgr, bottomIds);
|
||||
|
||||
List<String> leftIds = mgr.getIdsOn(ToolWindowAnchor.LEFT);
|
||||
boolean leftButtons = !settings.HIDE_TOOL_STRIPES && leftIds.size() > 0;
|
||||
boolean windowAtLeft = hasDockedVisible(mgr, leftIds);
|
||||
|
||||
List<String> rightIds = mgr.getIdsOn(ToolWindowAnchor.RIGHT);
|
||||
boolean rightBottoms = !settings.HIDE_TOOL_STRIPES && rightIds.size() > 0;
|
||||
boolean windowAtRight = hasDockedVisible(mgr, rightIds);
|
||||
|
||||
Insets insets = new Insets(0, 0, 0, 0);
|
||||
if (myWindow.getAnchor() == ToolWindowAnchor.TOP) {
|
||||
insets.top = topButtons ? 1 : 0;
|
||||
insets.left = leftButtons ? 1: 0;
|
||||
insets.right = rightBottoms ? 1: 0;
|
||||
insets.bottom = 1;
|
||||
} else if (myWindow.getAnchor() == ToolWindowAnchor.BOTTOM) {
|
||||
insets.top = 0;
|
||||
insets.left = leftButtons ? 1 : 0;
|
||||
insets.right = rightBottoms ? 1: 0;
|
||||
insets.bottom = bottomButtons ? 1 : 0;
|
||||
} else if (myWindow.getAnchor() == ToolWindowAnchor.LEFT) {
|
||||
insets.top = topButtons && !windowAtTop ? 1 : 0;
|
||||
insets.left = leftButtons ? 1: 0;
|
||||
insets.right = 0;
|
||||
insets.bottom = bottomButtons && !windowAtBottom ? 1 : 0;
|
||||
} else if (myWindow.getAnchor() == ToolWindowAnchor.RIGHT) {
|
||||
insets.top = topButtons && !windowAtTop ? 1: 0;
|
||||
insets.left = 1;
|
||||
insets.right = rightBottoms ? 1: 0;
|
||||
insets.bottom = bottomButtons && !windowAtBottom ? 1: 0;
|
||||
}
|
||||
|
||||
return insets;
|
||||
}
|
||||
|
||||
private boolean hasDockedVisible(ToolWindowManager mgr, List<String> ids) {
|
||||
for (String each : ids) {
|
||||
ToolWindow eachWnd = mgr.getToolWindow(each);
|
||||
if (eachWnd.isVisible()) {
|
||||
if (eachWnd.getType() == ToolWindowType.DOCKED) return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isBorderOpaque() {
|
||||
|
||||
@@ -60,7 +60,7 @@ public final class TitlePanel extends JPanel {
|
||||
|
||||
public final static Color ACTIVE_SIDE_BUTTON_BG = new Color(179, 197, 231);
|
||||
public final static Color INACTIVE_SIDE_BUTTON_BG = new Color(200, 200, 200);
|
||||
public static final int STRUT = 1;
|
||||
public static final int STRUT = 0;
|
||||
|
||||
TitlePanel() {
|
||||
super(new BorderLayout());
|
||||
|
||||
@@ -92,8 +92,12 @@ final class ToolWindowsPane extends JLayeredPane {
|
||||
// Splitters
|
||||
|
||||
myVerticalSplitter = new ThreeComponentsSplitter(true);
|
||||
myVerticalSplitter.setDividerWidth(0);
|
||||
myVerticalSplitter.setDividerMouseZoneSize(5);
|
||||
myVerticalSplitter.setBackground(Color.gray);
|
||||
myHorizontalSplitter = new ThreeComponentsSplitter(false);
|
||||
myHorizontalSplitter.setDividerWidth(0);
|
||||
myHorizontalSplitter.setDividerMouseZoneSize(5);
|
||||
myHorizontalSplitter.setBackground(Color.gray);
|
||||
|
||||
myVerticalSplitter.setInnerComponent(myHorizontalSplitter);
|
||||
|
||||
@@ -75,7 +75,6 @@ public class PositionPanel implements StatusBarWidget, StatusBarWidget.TextPrese
|
||||
return "#############";
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getAlignment() {
|
||||
return JComponent.CENTER_ALIGNMENT;
|
||||
}
|
||||
@@ -141,7 +140,7 @@ public class PositionPanel implements StatusBarWidget, StatusBarWidget.TextPrese
|
||||
|
||||
public void caretPositionChanged(final CaretEvent e) {
|
||||
final Editor editor = e.getEditor();
|
||||
if (FileEditorManager.getInstance(editor.getProject()).getSelectedTextEditor() == e.getEditor()) {
|
||||
if (editor.getProject() != null && FileEditorManager.getInstance(editor.getProject()).getSelectedTextEditor() == e.getEditor()) {
|
||||
updatePosition(editor);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user