00001 package edu.stanford.hci.r3.paper.layout;
00002
00003 import java.util.ArrayList;
00004 import java.util.List;
00005
00006 import edu.stanford.hci.r3.paper.Region;
00007 import edu.stanford.hci.r3.paper.Sheet;
00008 import edu.stanford.hci.r3.units.Inches;
00009 import edu.stanford.hci.r3.units.Units;
00010 import edu.stanford.hci.r3.units.coordinates.Coordinates;
00011 import edu.stanford.hci.r3.util.DebugUtils;
00012
00025 public class FlowPaperLayout {
00026
00033 private static void addRegionGroupToSheet(Sheet sheet, RegionGroup currRegionGroup,
00034 Inches xOffsetOfGroup, Inches yOffsetOfGroup) {
00035 List<Region> regions = currRegionGroup.getRegions();
00036 double offsetXInInches = currRegionGroup.getXOffsetInInches() + xOffsetOfGroup.getValue();
00037 double offsetYInInches = currRegionGroup.getYOffsetInInches() + yOffsetOfGroup.getValue();
00038 for (Region r : regions) {
00039 Coordinates regionOffset = currRegionGroup.getRegionOffset(r);
00040 sheet.addRegion(r,
00041 new Inches(offsetXInInches + regionOffset.getX().getValueInInches()),
00042 new Inches(offsetYInInches + regionOffset.getY().getValueInInches()));
00043 }
00044 }
00045
00050 public static void layout(Sheet targetSheet, List<Region> regions) {
00051 Units width = targetSheet.getWidth();
00052 Units height = targetSheet.getHeight();
00053 layout(targetSheet, regions, new Coordinates(new Inches(0), new Inches(0)), width, height,
00054 new Inches(0), new Inches(0));
00055 }
00056
00070 public static void layout(Sheet sheet, List<Region> regions, Coordinates sheetOffset,
00071 Units width, Units height, Units hPadding, Units vPadding) {
00072
00073 final double xOffset = sheetOffset.getX().getValueInInches();
00074 final double yOffset = sheetOffset.getY().getValueInInches();
00075
00076 final double widthOfLayoutAreaInInches = width.getValueInInches();
00077 final double heightOfLayoutAreaInInches = height.getValueInInches();
00078
00079 double relInchesX = 0;
00080 double relInchesY = 0;
00081
00082 final double hPaddingInInches = hPadding.getValueInInches();
00083
00084 double maxHeightOfRow = 0;
00085
00086
00087 final List<Region> currentRow = new ArrayList<Region>();
00088
00089 int count = 0;
00090 for (final Region currRegion : regions) {
00091
00092 final double currRegionWidthInInches = currRegion.getWidth().getValueInInches();
00093 final double currRegionHeightInInches = currRegion.getHeight().getValueInInches();
00094
00095
00096 if (relInchesX + currRegionWidthInInches + hPaddingInInches > widthOfLayoutAreaInInches) {
00097
00098
00099 final double slackSpace = widthOfLayoutAreaInInches - relInchesX;
00100 final int numItemsInThisRow = currentRow.size();
00101 final double extraSlackBetweenItems = slackSpace / (numItemsInThisRow - 1);
00102 double totalSlack = 0;
00103 for (Region regionToAdjust : currentRow) {
00104 Coordinates regionOffset = sheet.getRegionOffset(regionToAdjust);
00105 sheet.setRegionOffset(regionToAdjust, new Inches(regionOffset.getX()
00106 .getValueInInches()
00107 + totalSlack), regionOffset.getY());
00108 totalSlack += extraSlackBetweenItems;
00109 }
00110
00111
00112 currentRow.clear();
00113
00114 relInchesX = 0;
00115
00116 relInchesY += maxHeightOfRow + vPadding.getValueInInches();
00117
00118
00119 maxHeightOfRow = 0;
00120
00121
00122 if (relInchesY > heightOfLayoutAreaInInches) {
00123 DebugUtils.println("WARNING: We are stopping the layout after " + count
00124 + " items because we have exceeded the height of the layout area.");
00125 break;
00126 }
00127 }
00128 maxHeightOfRow = Math.max(maxHeightOfRow, currRegionHeightInInches);
00129
00130 sheet.addRegion(currRegion,
00131 new Inches(relInchesX + xOffset),
00132 new Inches(relInchesY + yOffset));
00133 currentRow.add(currRegion);
00134 relInchesX += currRegionWidthInInches + hPaddingInInches;
00135 count++;
00136 }
00137 DebugUtils.println("Laid out " + count + " items.");
00138 }
00139
00149 public static void layoutRegionGroups(Sheet sheet, List<RegionGroup> regionGroups,
00150 Coordinates sheetOffset, Units width, Units height, Units hPadding, Units vPadding) {
00151
00152 final double xOffset = sheetOffset.getX().getValueInInches();
00153 final double yOffset = sheetOffset.getY().getValueInInches();
00154
00155 final double widthOfLayoutAreaInInches = width.getValueInInches();
00156 final double heightOfLayoutAreaInInches = height.getValueInInches();
00157
00158 double relInchesX = 0;
00159 double relInchesY = 0;
00160
00161 final double hPaddingInInches = hPadding.getValueInInches();
00162
00163 double maxHeightOfRow = 0;
00164
00165
00166 final List<RegionGroup> currentRow = new ArrayList<RegionGroup>();
00167
00168 int count = 0;
00169 for (final RegionGroup currRegionGroup : regionGroups) {
00170
00171 final double currRegionWidthInInches = currRegionGroup.getWidth().getValueInInches();
00172 final double currRegionHeightInInches = currRegionGroup.getHeight().getValueInInches();
00173
00174
00175 if (relInchesX + currRegionWidthInInches + hPaddingInInches > widthOfLayoutAreaInInches) {
00176
00177
00178 final double slackSpace = widthOfLayoutAreaInInches - relInchesX;
00179 final int numItemsInThisRow = currentRow.size();
00180 final double extraSlackBetweenItems = slackSpace / (numItemsInThisRow - 1);
00181 double totalSlack = 0;
00182 for (RegionGroup regionToAdjust : currentRow) {
00183 for (Region r : regionToAdjust.getRegions()) {
00184 Coordinates regionOffset = sheet.getRegionOffset(r);
00185 sheet.setRegionOffset(r, new Inches(regionOffset.getX().getValueInInches()
00186 + totalSlack), regionOffset.getY());
00187 }
00188 totalSlack += extraSlackBetweenItems;
00189 }
00190
00191
00192 currentRow.clear();
00193
00194 relInchesX = 0;
00195
00196 relInchesY += maxHeightOfRow + vPadding.getValueInInches();
00197
00198
00199 maxHeightOfRow = 0;
00200
00201
00202 if (relInchesY > heightOfLayoutAreaInInches) {
00203 DebugUtils.println("WARNING: We are stopping the layout after " + count
00204 + " items because we have exceeded the height of the layout area.");
00205 break;
00206 }
00207 }
00208 maxHeightOfRow = Math.max(maxHeightOfRow, currRegionHeightInInches);
00209
00210 addRegionGroupToSheet(sheet, currRegionGroup, new Inches(relInchesX + xOffset),
00211 new Inches(relInchesY + yOffset));
00212
00213 currentRow.add(currRegionGroup);
00214 relInchesX += currRegionWidthInInches + hPaddingInInches;
00215 count++;
00216 }
00217 DebugUtils.println("Laid out " + count + " items.");
00218 }
00219 }