/*
* Copyright 2013 Hewlett-Packard Development Company, L.P
*
* 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.hp.alm.ali.idea.ui;
import com.intellij.openapi.util.IconLoader;
import javax.swing.JLabel;
import javax.swing.JPanel;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Point;
import java.awt.Window;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public abstract class GridBagSplitter extends MouseAdapter {
private Point startPosition;
private int[] rowHeights;
private double[] rowWeights;
private int firstComponent;
private final GridBagLayout layout;
private final int pos;
private JPanel gridPanel;
private Window window;
private JLabel splitter;
public GridBagSplitter(Window window, JPanel gridPanel, int pos) {
this.window = window;
this.gridPanel = gridPanel;
this.pos = pos;
this.layout = (GridBagLayout) gridPanel.getLayout();
splitter = new JLabel(IconLoader.getIcon("/general/splitGlueV.png"));
splitter.addMouseListener(this);
splitter.addMouseMotionListener(this);
}
public void mouseEntered(MouseEvent mouseEvent) {
if(startPosition == null) {
rowHeights = layout.getLayoutDimensions()[1];
rowWeights = layout.getLayoutWeights()[1];
firstComponent = - 1;
for(int i = pos; i > 0; i--) {
if(rowWeights[i] > 0) {
firstComponent = i;
break;
}
}
if(firstComponent >= 0) {
window.setCursor(Cursor.getPredefinedCursor(Cursor.S_RESIZE_CURSOR));
}
}
}
public void mouseExited(MouseEvent mouseEvent) {
if(startPosition == null) {
window.setCursor(Cursor.getDefaultCursor());
}
}
public void mousePressed(MouseEvent mouseEvent) {
if(firstComponent >= 0) {
startPosition = mouseEvent.getLocationOnScreen();
}
}
public void mouseReleased(MouseEvent mouseEvent) {
if(startPosition != null) {
window.setCursor(Cursor.getDefaultCursor());
startPosition = null;
}
}
public void mouseDragged(MouseEvent mouseEvent) {
if(startPosition != null) {
Point endPosition = mouseEvent.getLocationOnScreen();
Component first = getComponentForRow(firstComponent);
Component second = getComponentForRow(pos + 1);
int diff = Math.max(endPosition.y - startPosition.y, first.getPreferredSize().height - rowHeights[firstComponent]);
diff = Math.min(diff, rowHeights[pos + 1] - second.getPreferredSize().height);
for(int i = 0; i < rowHeights.length; i++) {
if(rowWeights[i] > 0) {
Component comp = getComponentForRow(i);
double weight = (double) (rowHeights[i] - comp.getPreferredSize().height);
if(i == firstComponent) {
weight += diff;
} else if(i == pos + 1) {
weight -= diff;
}
// make sure weight remains > 0 for the layout to continue working properly
setComponentWeight(layout, Math.max(0.00001, weight), comp);
}
}
layout.layoutContainer(gridPanel);
gridPanel.revalidate();
gridPanel.repaint();
}
}
protected abstract Component getComponentForRow(int n);
private void setComponentWeight(GridBagLayout layout, double weighty, Component component) {
GridBagConstraints c = layout.getConstraints(component);
c.weighty = weighty;
layout.setConstraints(component, c);
}
public Component getComponent() {
return splitter;
}
}