Index: core/src/org/netbeans/core/windows/frames/PerimeterPane.java =================================================================== RCS file: /cvs/core/src/org/netbeans/core/windows/frames/PerimeterPane.java,v retrieving revision 1.23 diff -u -r1.23 PerimeterPane.java --- core/src/org/netbeans/core/windows/frames/PerimeterPane.java 4 Feb 2003 16:40:07 -0000 1.23 +++ core/src/org/netbeans/core/windows/frames/PerimeterPane.java 17 Feb 2003 16:53:53 -0000 @@ -74,6 +74,76 @@ g.fillRect (0,0,getWidth(), getHeight()); } } + + + // Fields used by dragging paint. + private boolean drag; + private Rectangle horiz; + private Rectangle vert; + private Point newLoc; + private int deltaX; + private int deltaY; + private int orientation; + + private void setDragging(boolean drag) { + this.drag = drag; + + if(!drag) { + horiz = null; + vert = null; + newLoc = null; + deltaX = 0; + deltaY = 0; + orientation = 0; + } + } + + /** Overrides superclass method, to provide more efficient paint during + * dragging. */ + public void paint(Graphics g) { + super.paint(g); + + if(drag) { + Rectangle h = horiz; + Rectangle v = vert; + + Point newPoint = newLoc; + + if(!getBounds().contains(newPoint)) { + return; + } + + Color old = g.getColor(); + g.setColor(Color.darkGray); + + // Draw horizontal split. + if(h != null && newPoint != null) { + h.setLocation(h.x, newPoint.y + deltaY); + if(orientation == 3) { // WEST + h.setBounds(h.x, h.y, (newPoint.x + deltaX) - h.x, h.height); + } + else if(orientation == 4) { + h.setBounds((newPoint.x + deltaX), h.y, h.width - ((newPoint.x + deltaX) - h.x), h.height); + } + g.fillRect(h.x, h.y, h.width, h.height); + } + + // Draw vertical split. + if(v != null && newPoint != null) { + v.setLocation(newPoint.x + deltaX, v.y); + if(orientation == 1) { // NORTH + v.setBounds(v.x, v.y, v.width, (newPoint.y + deltaY) - v.y); + } + else if(orientation == 2) { // SOUTH + v.setBounds(v.x, (newPoint.y + deltaY), v.width, v.height - ((newPoint.y + deltaY) - v.y)); + } + + g.fillRect(v.x, v.y, v.width, v.height); + } + + g.setColor(old); + } + } /** * Relese resources so that PerimeterPane instance can be garbage collected. @@ -304,6 +374,10 @@ // save the old cursor... int oldCursorType = pPane.getCursor().getType(); + + // Fields working when dragging 'split' + private Rectangle horizontal; + private Rectangle vertical; boolean sizingCursorSet = false; public PerimeterGapListener() { @@ -311,22 +385,182 @@ public void mousePressed(final MouseEvent me) { if ((me.getModifiers() & me.BUTTON1_MASK) != 0) { - // get original position + // update mouse location mouseLocation = me.getPoint(); - // resizing if clicked directly on JPanel - resizing = (pPane.getComponentAt(mouseLocation) == pPane); + + Point point = mouseLocation; + // No resizing if not clicked directly at pane. + if(pPane.getComponentAt(point) != pPane) { + return; + } + + // Retrieve split rectangles. + Component top = (Component)pPane.components.get(PerimeterLayout.NORTH); + Component bottom = (Component)pPane.components.get(PerimeterLayout.SOUTH); + Component center = (Component)pPane.components.get(PerimeterLayout.CENTER); + Component left = (Component)pPane.components.get(PerimeterLayout.WEST); + Component right = (Component)pPane.components.get(PerimeterLayout.EAST); + + // is horizontal? + if(top != null && center != null) { + // is horizontal between top and center. + tryToSetHorizontal(top, center, point.y); + } + if(horizontal == null && center != null && bottom != null) { + // is between center and bottom + tryToSetHorizontal(center, bottom, point.y); + } + // when center is missing also left or right could be under top/ or above bottom. + if(horizontal == null && top != null && left != null && center == null) { + tryToSetHorizontal(top, left, point.y); + } + if(horizontal == null && top != null && right != null && center == null) { + tryToSetHorizontal(top, right, point.y); + } + if(horizontal == null && left != null && bottom != null && center == null) { + tryToSetHorizontal(left, bottom, point.y); + } + if(horizontal == null && right != null && bottom != null && center == null) { + tryToSetHorizontal(right, bottom, point.y); + } + // even top and bottom could be side by side. + if(horizontal == null && top != null && bottom != null && center == null + && (left == null || (left.getBounds().x < top.getBounds().x + || left.getBounds().x < bottom.getBounds().x)) + && (right == null + || ((top.getBounds().x + top.getBounds().width) < (right.getBounds().x + right.getBounds().width) + || (bottom.getBounds().x + bottom.getBounds().width) < (right.getBounds().x + right.getBounds().width)))) { + // is between top and bottom while center is missing. + tryToSetHorizontal(top, bottom, point.y); + } + + + + // is vertical? + if(left != null && center != null) { + // is horizontal between left and center. + tryToSetVertical(left, center, point.x); + } + if(vertical == null && center != null && right != null) { + // is between center and right + tryToSetVertical(center, right, point.x); + } + // when center is missing also top or bottom could be right from left or left from righ. + if(vertical == null && left != null && top != null && center == null) { + tryToSetVertical(left, top, point.x); + } + if(vertical == null && left != null && bottom != null && center == null) { + tryToSetVertical(left, bottom, point.x); + } + if(vertical == null && top != null && right != null && center == null) { + tryToSetVertical(top, right, point.x); + } + if(vertical == null && bottom != null && right != null && center == null) { + tryToSetVertical(bottom, right, point.x); + } + // even left and right could be side by side. + if(vertical == null && left != null && right != null && center == null + && (top == null || (top.getBounds().y < left.getBounds().y || top.getBounds().y < right.getBounds().y)) + && (bottom == null + || ((left.getBounds().y + left.getBounds().height) < (top.getBounds().y + top.getBounds().height) + || (right.getBounds().y + right.getBounds().height) < (bottom.getBounds().y + bottom.getBounds().height)))) { + // is between left and right while center is missing. + tryToSetVertical(left, right, point.x); + } + + // No resizing if the splits were not found. + if(horizontal != null || vertical != null) { + resizing = true; + } else { + resizing = false; + return; + } + + // Sets values to pane. + pPane.horiz = horizontal; + pPane.vert = vertical; + if(vertical != null) { + pPane.deltaX = point.x - vertical.x; + } + if(horizontal != null) { + pPane.deltaY = point.y - horizontal.y; + } + pPane.newLoc = point; + + // Set orientation when both split are positioned. + if(horizontal != null && vertical != null) { + if(!vertical.contains(point.x, point.y + (horizontal.height + 1))) { + pPane.orientation = 1; // NORTH + } + else if(!vertical.contains(point.x, point.y - (horizontal.height + 1))) { + pPane.orientation = 2; // SOUTH + } + else if(!horizontal.contains(point.x + (vertical.width + 1), point.y)) { + pPane.orientation = 3; // WEST + } + else if(!horizontal.contains(point.x - (vertical.width + 1), point.y)) { + pPane.orientation = 4; // EAST + } + } } } + + private void tryToSetHorizontal(Component top, Component bottom, int y) { + if((top.getBounds().y + top.getBounds().height) <= y + && bottom.getBounds().y >= y) { + horizontal = getHorizontalSplitRect(top.getBounds(), bottom.getBounds()); + } + } + + private void tryToSetVertical(Component left, Component right, int x) { + if((left.getBounds().x + left.getBounds().width) <= x + && right.getBounds().x >= x) { + vertical = getVerticalSplitRect(left.getBounds(), right.getBounds()); + } + } + private Rectangle getHorizontalSplitRect(Rectangle top, Rectangle bottom) { + return new Rectangle( + Math.min(top.x, bottom.x), + top.y + top.height, + Math.max(top.width, bottom.width), + bottom.y - (top.y + top.height) + );; + } + + private Rectangle getVerticalSplitRect(Rectangle left, Rectangle right) { + return new Rectangle( + left.x + left.width, + Math.min(left.y, right.y), + right.x - (left.x + left.width), + Math.max(left.height, right.height) + ); + } + public void mouseReleased(final MouseEvent me) { // resizing done resizing = false; + + horizontal = null; + vertical = null; + + pPane.setDragging(false); dragging = false; + + Point newLoc = me.getPoint(); + Rectangle rect = pPane.getBounds(); + rect.setLocation(0, 0); + if(rect.contains(newLoc)) { + updateComponents(newLoc); + } pPane.setCursor(Cursor.getPredefinedCursor(oldCursorType)); + pPane.repaint(); } public void mouseDragged(final MouseEvent me) { if (resizing == true) { + pPane.setDragging(true); + dragging = true; // get new position Point newLoc = me.getPoint(); @@ -338,57 +572,107 @@ // only move if greater than CHANGE pixels than the last position if (newLoc.distance(mouseLocation) > CHANGE) { - HashMap comps = pPane.components; - Rectangle pRect = pPane.getBounds(); - // resize appropriate comps if mouse pressed in proper pos - // e.g. for the SOUTH component, we check that we are south - // of the desktop/NORTH component and north of the SOUTH - // component - if (outcodes[NORTHSIDE] == Rectangle.OUT_BOTTOM) { - // resize the north panel - Component comp = (Component)comps.get(PerimeterLayout.NORTH); - if(comp != null) { // #25357 - Rectangle rect = comp.getBounds(); - rect.height = newLoc.y; - comp.setBounds(rect); - } - } - if (outcodes[SOUTHSIDE] == Rectangle.OUT_TOP) { - // resize the south panel - Component comp = (Component)comps.get(PerimeterLayout.SOUTH); - if(comp != null) { // #25357 - Rectangle rect = comp.getBounds(); - rect.height = pRect.height - newLoc.y - layout.getGap(); - comp.setBounds(rect); + // updateComponents(newLoc); // old fashion + + pPane.newLoc = newLoc; + + Rectangle h = horiz; + Rectangle v = vert; + + + Point newPoint = newLoc; + // Repaint new splits. + if(getBounds().contains(newPoint)) { + // Draw horizontal split. + if(h != null && newPoint != null) { + Rectangle hh = (Rectangle)h.clone(); + hh.setLocation(hh.x, newPoint.y + deltaY); + if(orientation == 3) { // WEST + hh.setBounds(hh.x, hh.y, (newPoint.x + deltaX) - hh.x, h.height); + } + else if(orientation == 4) { + hh.setBounds((newPoint.x + deltaX), hh.y, hh.width - ((newPoint.x + deltaX) - h.x), hh.height); + } + h = h.union(hh); } - } - if (outcodes[EASTSIDE] == Rectangle.OUT_LEFT) { - // resize the east panel - Component comp = (Component)comps.get(PerimeterLayout.EAST); - if(comp != null) { // #25357 - Rectangle rect = comp.getBounds(); - rect.width = pRect.width - newLoc.x - layout.getGap(); - rect.x = newLoc.x; - comp.setBounds(rect); + + // Draw vertical split. + if(v != null && newPoint != null) { + Rectangle vv = (Rectangle)v.clone(); + vv.setLocation(newPoint.x + deltaX, vv.y); + if(orientation == 1) { // NORTH + vv.setBounds(vv.x, vv.y, vv.width, (newPoint.y + deltaY) - vv.y); + } + else if(orientation == 2) { // SOUTH + vv.setBounds(vv.x, (newPoint.y + deltaY), vv.width, vv.height - ((newPoint.y + deltaY) - vv.y)); + } + v = v.union(vv); } } - if (outcodes[WESTSIDE] == Rectangle.OUT_RIGHT) { - // resize the west panel - Component comp = (Component)comps.get(PerimeterLayout.WEST); - if(comp != null) { // #25357 - Rectangle rect = comp.getBounds(); - rect.width = newLoc.x; - comp.setBounds(rect); - } + + // Paint regions: horizontal and vertical if necessary. + if(h != null) { + pPane.repaint(h); + } + if(v != null) { + pPane.repaint(v); } - + // update the postition mouseLocation = newLoc; - pPane.revalidate(); } } } + private void updateComponents(Point newLoc) { + HashMap comps = pPane.components; + Rectangle pRect = pPane.getBounds(); + // resize appropriate comps if mouse pressed in proper pos + // e.g. for the SOUTH component, we check that we are south + // of the desktop/NORTH component and north of the SOUTH + // component + if (outcodes[NORTHSIDE] == Rectangle.OUT_BOTTOM) { + // resize the north panel + Component comp = (Component)comps.get(PerimeterLayout.NORTH); + if(comp != null) { // #25357 + Rectangle rect = comp.getBounds(); + rect.height = newLoc.y; + comp.setBounds(rect); + } + } + if (outcodes[SOUTHSIDE] == Rectangle.OUT_TOP) { + // resize the south panel + Component comp = (Component)comps.get(PerimeterLayout.SOUTH); + if(comp != null) { // #25357 + Rectangle rect = comp.getBounds(); + rect.height = pRect.height - newLoc.y - layout.getGap(); + comp.setBounds(rect); + } + } + if (outcodes[EASTSIDE] == Rectangle.OUT_LEFT) { + // resize the east panel + Component comp = (Component)comps.get(PerimeterLayout.EAST); + if(comp != null) { // #25357 + Rectangle rect = comp.getBounds(); + rect.width = pRect.width - newLoc.x - layout.getGap(); + rect.x = newLoc.x; + comp.setBounds(rect); + } + } + if (outcodes[WESTSIDE] == Rectangle.OUT_RIGHT) { + // resize the west panel + Component comp = (Component)comps.get(PerimeterLayout.WEST); + if(comp != null) { // #25357 + Rectangle rect = comp.getBounds(); + rect.width = newLoc.x; + comp.setBounds(rect); + } + } + pPane.revalidate(); + } + + + /** Required for MouseMotionListener. */ public void mouseMoved(final java.awt.event.MouseEvent me) { Component comp = pPane.getComponentAt(me.getPoint()); @@ -473,7 +757,9 @@ compRect.grow(gap * 2, gap * 2); // return an outcode if the mouse is within the gaps between comp's - return (compRect.contains(newLoc) ? comp.getBounds().outcode(newLoc) : 0); + int outcode = (compRect.contains(newLoc) ? comp.getBounds().outcode(newLoc) : 0); + + return outcode; } // note that the center component is not considered when choosing