org.netbeans.modules.visual.layout.FlowLayout Maven / Gradle / Ivy
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.netbeans.modules.visual.layout;
import org.netbeans.api.visual.widget.Widget;
import org.netbeans.api.visual.layout.Layout;
import org.netbeans.api.visual.layout.LayoutFactory;
import java.awt.*;
import java.util.*;
/**
* @author David Kaspar
*/
public final class FlowLayout implements Layout {
private boolean verticalOrientation;
private LayoutFactory.SerialAlignment alignment;
private int gap;
public FlowLayout (boolean verticalOrientation, LayoutFactory.SerialAlignment alignment, int gap) {
this.verticalOrientation = verticalOrientation;
this.alignment = alignment;
this.gap = gap;
}
public void layout (Widget widget) {
int max = 0;
Collection children = widget.getChildren ();
if (verticalOrientation) {
for (Widget child : children) {
if (! child.isVisible ())
continue;
Rectangle preferredBounds = child.getPreferredBounds ();
int i = preferredBounds.width;
if (i > max)
max = i;
}
int pos = 0;
for (Widget child : children) {
Rectangle preferredBounds = child.getPreferredBounds ();
int x = preferredBounds.x;
int y = preferredBounds.y;
int width = preferredBounds.width;
int height = preferredBounds.height;
int lx = -x;
int ly = pos - y;
switch (alignment) {
case CENTER:
lx += (max - width) / 2;
break;
case JUSTIFY:
width = max;
break;
case LEFT_TOP:
break;
case RIGHT_BOTTOM:
lx += max - width;
break;
}
if (child.isVisible ()) {
child.resolveBounds (new Point (lx, ly), new Rectangle (x, y, width, height));
pos += height + gap;
} else
child.resolveBounds (new Point (lx, ly), new Rectangle (x, y, 0, 0));
}
} else {
for (Widget child : children) {
if (!child.isVisible ())
continue;
Rectangle preferredBounds = child.getPreferredBounds ();
int i = preferredBounds.height;
if (i > max)
max = i;
}
int pos = 0;
for (Widget child : children) {
Rectangle preferredBounds = child.getPreferredBounds ();
int x = preferredBounds.x;
int y = preferredBounds.y;
int width = preferredBounds.width;
int height = preferredBounds.height;
int lx = pos - x;
int ly = -y;
switch (alignment) {
case CENTER:
ly += (max - height) / 2;
break;
case JUSTIFY:
height = max;
break;
case LEFT_TOP:
break;
case RIGHT_BOTTOM:
ly += max - height;
break;
}
if (child.isVisible ()) {
child.resolveBounds (new Point (lx, ly), new Rectangle (x, y, width, height));
pos += width + gap;
} else
child.resolveBounds (new Point (lx, ly), new Rectangle (x, y, 0, 0));
}
}
}
public boolean requiresJustification (Widget widget) {
return true;
}
public void justify (Widget widget) {
Rectangle parentBounds = widget.getClientArea ();
int totalWeight = 0;
int totalGap = 0;
java.util.List children = widget.getChildren ();
for (int a = 0; a < children.size (); a ++) {
Widget child = children.get (a);
if (! child.isVisible ())
continue;
totalWeight += resolveWeight (widget, child);
if (a > 0)
totalGap -= gap;
if (verticalOrientation)
totalGap -= child.getBounds ().height;
else
totalGap -= child.getBounds ().width;
}
totalGap += verticalOrientation ? parentBounds.height : parentBounds.width;
if (totalGap < 0)
totalWeight = totalGap = 0;
int gapAdd = 0;
int weightAdd = 0;
int parentX1 = parentBounds.x;
int parentX2 = parentX1 + parentBounds.width;
int parentY1 = parentBounds.y;
int parentY2 = parentY1 + parentBounds.height;
for (Widget child : widget.getChildren ()) {
Point childLocation = child.getLocation ();
Rectangle childBounds = child.getBounds ();
if (verticalOrientation) {
switch (alignment) {
case CENTER:
childLocation.x = (parentX1 + parentX2 - childBounds.width) / 2;
break;
case JUSTIFY:
childLocation.x = parentX1;
childBounds.width = parentX2 - parentX1;
break;
case LEFT_TOP:
childLocation.x = parentX1;
break;
case RIGHT_BOTTOM:
childLocation.x = parentX2 - childBounds.width;
break;
}
if (totalWeight > 0 && child.isVisible ()) {
childLocation.y += gapAdd;
int weight = resolveWeight (widget, child);
int gap = (weightAdd + weight) * totalGap / totalWeight;
childBounds.height += gap - gapAdd;
gapAdd = gap;
weightAdd += weight;
}
childLocation.x -= childBounds.x;
childLocation.y += parentY1;
} else {
switch (alignment) {
case CENTER:
childLocation.y = (parentY1 + parentY2 - childBounds.height) / 2;
break;
case JUSTIFY:
childLocation.y = parentY1;
childBounds.height = parentY2 - parentY1;
break;
case LEFT_TOP:
childLocation.y = parentY1;
break;
case RIGHT_BOTTOM:
childLocation.y = parentY2 - childBounds.height;
break;
}
if (totalWeight > 0 && child.isVisible ()) {
childLocation.x += gapAdd;
int weight = resolveWeight (widget, child);
int gap = (weightAdd + weight) * totalGap / totalWeight;
childBounds.width += gap - gapAdd;
gapAdd = gap;
weightAdd += weight;
}
childLocation.y -= childBounds.y;
childLocation.x += parentX1;
}
child.resolveBounds (childLocation, childBounds);
}
}
private static int resolveWeight (Widget widget, Widget child) {
Object o = widget.getChildConstraint (child);
if (o instanceof Number) {
int weight = ((Number) o).intValue ();
if (weight > 0)
return weight;
}
return 0;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy