summaryrefslogtreecommitdiff
path: root/platform/platform-api/src/com/intellij/openapi/ui/OnePixelDivider.java
diff options
context:
space:
mode:
Diffstat (limited to 'platform/platform-api/src/com/intellij/openapi/ui/OnePixelDivider.java')
-rw-r--r--platform/platform-api/src/com/intellij/openapi/ui/OnePixelDivider.java233
1 files changed, 233 insertions, 0 deletions
diff --git a/platform/platform-api/src/com/intellij/openapi/ui/OnePixelDivider.java b/platform/platform-api/src/com/intellij/openapi/ui/OnePixelDivider.java
new file mode 100644
index 000000000000..2b0097005dc1
--- /dev/null
+++ b/platform/platform-api/src/com/intellij/openapi/ui/OnePixelDivider.java
@@ -0,0 +1,233 @@
+/*
+ * Copyright 2000-2014 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.openapi.ui;
+
+import com.intellij.openapi.Disposable;
+import com.intellij.openapi.util.Disposer;
+import com.intellij.openapi.util.SystemInfo;
+import com.intellij.openapi.util.Weighted;
+import com.intellij.openapi.wm.IdeGlassPane;
+import com.intellij.openapi.wm.IdeGlassPaneUtil;
+import com.intellij.ui.Gray;
+import com.intellij.ui.JBColor;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+
+/**
+ * @author Konstantin Bulenkov
+ */
+public class OnePixelDivider extends Divider {
+ private boolean myVertical;
+ private Splitter mySplitter;
+ private boolean myResizeEnabled;
+ private boolean mySwitchOrientationEnabled;
+ protected Point myPoint;
+ private IdeGlassPane myGlassPane;
+ private final MouseAdapter myListener = new MyMouseAdapter();
+ private Disposable myDisposable;
+
+ public OnePixelDivider(boolean vertical, Splitter splitter) {
+ super(new GridBagLayout());
+ mySplitter = splitter;
+ myResizeEnabled = true;
+ mySwitchOrientationEnabled = false;
+ setFocusable(false);
+ enableEvents(AWTEvent.MOUSE_EVENT_MASK | AWTEvent.MOUSE_MOTION_EVENT_MASK);
+ //setOpaque(false);
+ setOrientation(vertical);
+ setBackground(new JBColor(Gray._153.withAlpha(128), Gray._100.withAlpha(128)));
+ }
+
+ @Override
+ public void addNotify() {
+ super.addNotify();
+ init();
+ }
+
+ @Override
+ public void removeNotify() {
+ super.removeNotify();
+ if (myDisposable != null && !Disposer.isDisposed(myDisposable)) {
+ Disposer.dispose(myDisposable);
+ }
+ }
+
+ private boolean dragging = false;
+ private class MyMouseAdapter extends MouseAdapter implements Weighted {
+ @Override
+ public void mousePressed(MouseEvent e) {
+ dragging = isInDragZone(e);
+ _processMouseEvent(e);
+ }
+
+ boolean isInDragZone(MouseEvent e) {
+ final MouseEvent event = getTargetEvent(e);
+ final Point p = event.getPoint();
+ final int r = Math.abs(isVertical() ? p.y : p.x);
+ return r < 6;
+ }
+
+ @Override
+ public void mouseReleased(MouseEvent e) {
+ _processMouseEvent(e);
+ dragging = false;
+ }
+
+ @Override
+ public void mouseMoved(MouseEvent e) {
+ final OnePixelDivider divider = OnePixelDivider.this;
+ if (isInDragZone(e)) {
+ myGlassPane.setCursor(divider.getCursor(), divider);
+ } else {
+ myGlassPane.setCursor(null, divider);
+ }
+ _processMouseMotionEvent(e);
+ }
+
+ @Override
+ public void mouseDragged(MouseEvent e) {
+ _processMouseMotionEvent(e);
+ }
+ @Override
+ public double getWeight() {
+ return 1;
+ }
+ private void _processMouseMotionEvent(MouseEvent e) {
+ MouseEvent event = getTargetEvent(e);
+ if (event == null) {
+ myGlassPane.setCursor(null, myListener);
+ return;
+ }
+
+ processMouseMotionEvent(event);
+ if (event.isConsumed()) {
+ e.consume();
+ }
+ }
+
+ private void _processMouseEvent(MouseEvent e) {
+ MouseEvent event = getTargetEvent(e);
+ if (event == null) {
+ myGlassPane.setCursor(null, myListener);
+ return;
+ }
+
+ processMouseEvent(event);
+ if (event.isConsumed()) {
+ e.consume();
+ }
+ }
+ }
+
+ private MouseEvent getTargetEvent(MouseEvent e) {
+ return SwingUtilities.convertMouseEvent(e.getComponent(), e, this);
+ }
+
+ private void init() {
+ myGlassPane = IdeGlassPaneUtil.find(this);
+ myDisposable = Disposer.newDisposable();
+ myGlassPane.addMouseMotionPreprocessor(myListener, myDisposable);
+ myGlassPane.addMousePreprocessor(myListener, myDisposable);
+ }
+
+ public void setOrientation(boolean vertical) {
+ removeAll();
+ myVertical = vertical;
+ final int cursorType = isVertical() ? Cursor.N_RESIZE_CURSOR : Cursor.W_RESIZE_CURSOR;
+ setCursor(Cursor.getPredefinedCursor(cursorType));
+ }
+
+ @Override
+ protected void processMouseMotionEvent(MouseEvent e) {
+ super.processMouseMotionEvent(e);
+ if (!myResizeEnabled) return;
+ if (MouseEvent.MOUSE_DRAGGED == e.getID() && dragging) {
+ myPoint = SwingUtilities.convertPoint(this, e.getPoint(), mySplitter);
+ float proportion;
+ final float firstMinProportion = getMinProportion(mySplitter.getFirstComponent());
+ final float secondMinProportion = getMinProportion(mySplitter.getSecondComponent());
+ if (isVertical()) {
+ if (getHeight() > 0) {
+ proportion = Math.min(1.0f, Math
+ .max(.0f, Math.min(Math.max(firstMinProportion, (float)myPoint.y / (float)mySplitter.getHeight()), 1 - secondMinProportion)));
+ mySplitter.setProportion(proportion);
+ }
+ }
+ else {
+ if (getWidth() > 0) {
+ proportion = Math.min(1.0f, Math.max(.0f, Math.min(
+ Math.max(firstMinProportion, (float)myPoint.x / (float)mySplitter.getWidth()), 1 - secondMinProportion)));
+ mySplitter.setProportion(proportion);
+ }
+ }
+ }
+ }
+
+ private float getMinProportion(JComponent component) {
+ if (component != null &&
+ mySplitter.getFirstComponent() != null &&
+ mySplitter.getFirstComponent().isVisible() &&
+ mySplitter.getSecondComponent() != null &&
+ mySplitter.getSecondComponent().isVisible()) {
+ if (isVertical()) {
+ return (float)component.getMinimumSize().height / (float)(mySplitter.getHeight() - 1);
+ } else {
+ return (float)component.getMinimumSize().width / (float)(mySplitter.getWidth() - 1);
+ }
+ }
+
+ return 0.0f;
+ }
+
+ @Override
+ protected void processMouseEvent(MouseEvent e) {
+ super.processMouseEvent(e);
+ if (e.getID() == MouseEvent.MOUSE_CLICKED) {
+ if (mySwitchOrientationEnabled
+ && e.getClickCount() == 1
+ && SwingUtilities.isLeftMouseButton(e) && (SystemInfo.isMac ? e.isMetaDown() : e.isControlDown())) {
+ mySplitter.setOrientation(!mySplitter.getOrientation());
+ }
+ if (myResizeEnabled && e.getClickCount() == 2) {
+ mySplitter.setProportion(.5f);
+ }
+ }
+ }
+
+ public void setResizeEnabled(boolean resizeEnabled) {
+ myResizeEnabled = resizeEnabled;
+ if (!myResizeEnabled) {
+ setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
+ }
+ else {
+ setCursor(isVertical() ?
+ Cursor.getPredefinedCursor(Cursor.N_RESIZE_CURSOR) :
+ Cursor.getPredefinedCursor(Cursor.W_RESIZE_CURSOR));
+ }
+ }
+
+ public void setSwitchOrientationEnabled(boolean switchOrientationEnabled) {
+ mySwitchOrientationEnabled = switchOrientationEnabled;
+ }
+
+
+ public boolean isVertical() {
+ return myVertical;
+ }
+}