package jp.ac.kyutech.mns.ist; import java.awt.event.KeyEvent; import java.awt.geom.Rectangle2D; import java.util.ArrayList; import java.util.Collection; import java.util.Timer; import java.util.TimerTask; import java.util.TreeMap; import jp.ac.kyutech.mns.ist.sheetmap.MatrixHolder; import edu.umd.cs.piccolo.PCamera; import edu.umd.cs.piccolo.activities.PActivity; import edu.umd.cs.piccolo.util.PBounds; public class LayoutAbstract { PCamera camera; // ArrayList<LayoutContent> sorted; MatrixHolder<LayoutContent> matrix; int rownum_or_colnum = -1; public LayoutAbstract(PCamera cam){ camera = cam; // sorted = new ArrayList<LayoutContent>(); matrix = new MatrixHolder<LayoutContent>(); } //カーソルキーで上下左右するときに,次のフォーカスを探す // public LayoutContent getNext(int cur, int offset){ // int size = sorted.size(); // int expect = cur + offset; // if (size <= expect) { // if (cur == size-1) return null; else return sorted.get(size-1); // } else if (expect < 0){ // if (cur == 0) return null; else return sorted.get(0); // } else { // return sorted.get(expect); // } // } public LayoutContent getUDLR(int keyCode, LayoutContent currentFocus){ LayoutContent lc = matrix.getUDLR(keyCode, currentFocus); if (lc == null && keyCode == KeyEvent.VK_LEFT){ lc = matrix.getPreviousRowTail(currentFocus); } if (lc == null && keyCode == KeyEvent.VK_RIGHT){ lc = matrix.getNextRowHead(currentFocus); } return lc; } public void layout(int wait, LayoutTarget target){ class LayoutTask extends TimerTask{ ArrayList<LayoutContent> cnt; LayoutTask(ArrayList<LayoutContent> _cnt){ cnt = _cnt; } public void run(){ ArrayList<PActivity> palist = move(cnt); long mtime = System.currentTimeMillis(); if (palist == null) return; for (PActivity pact : palist) if (pact != null) pact.setStartTime(mtime); } } Timer t = new Timer(); t.schedule(new LayoutTask(target.getLayoutContents()), wait); //カーソルキー移動用の配列追加 // sorted.clear(); // sorted.addAll(target.getLayoutContents()); } //縦方向にならべるレイアウト public ArrayList<PActivity> move(ArrayList<LayoutContent> cnt){ int varticalNum = getBestFitLayoutV(cnt, camera.getViewBounds(), 0, 0); ArrayList<PActivity> palist = new ArrayList<PActivity>(); int ix=0,iy=0; double x = 0, y = 0, xmax = 0, w = 0; double xgap = 0, ygap = 0; int varticalCount = 0; matrix.removeAll(); for(LayoutContent pn: cnt){ if (!pn.hasContent()) continue; PActivity pa = pn.animateToPositionScaleRotation(x, y, 1, 0, 1000); // System.out.println("x y "+x+" "+y); matrix.put(ix, iy, pn); palist.add(pa); y += pn.getFullBounds().getHeight() + ygap; iy++; // x += pn.getFullBoundsReference().getWidth() + xgap; if (xmax < pn.getFullBounds().getWidth()) xmax = pn.getFullBounds().getWidth(); varticalCount++; if (varticalCount == varticalNum){ varticalCount = 0; w = w + xmax + xgap; x = w; y = 0; xmax = 0; ix++; iy=0; } } return palist; } public Rectangle2D maxContent(ArrayList<LayoutContent> cnt){ Rectangle2D maximumDim = null; double maxDimSq = 0; for(LayoutContent fr: cnt){ Rectangle2D temp = fr.getFullBounds(); double sq = temp.getWidth()*temp.getHeight(); if (maxDimSq < sq){ maxDimSq = sq; maximumDim = temp; } } return maximumDim; } public PBounds contentregion(LayoutTarget target){ ArrayList<LayoutContent> cnt = target.getLayoutContents(); int varticalNum = getBestFitLayoutV(cnt, camera.getViewBounds(), 0, 0); PBounds returnPB = new PBounds(); double x = 0, y = 0, xmax = 0, w = 0; double xgap = 0, ygap = 0; int varticalCount = 0; for(LayoutContent pn: cnt){ if (!pn.hasContent()) continue; if (returnPB != null) { PBounds aPB = new PBounds(pn.mysize()); aPB.setOrigin(x,y); returnPB.add(aPB); } y += pn.getFullBounds().getHeight() + ygap; // x += pn.getFullBoundsReference().getWidth() + xgap; if (xmax < pn.getFullBounds().getWidth()) xmax = pn.getFullBounds().getWidth(); varticalCount++; if (varticalCount == varticalNum){ varticalCount = 0; w = w + xmax + xgap; x = w; y = 0; xmax = 0; } } return returnPB; } public int getBestFitLayoutV(Collection<LayoutContent> rects2, Rectangle2D availableScreenSize, double xgap, double ygap) { ArrayList<Rectangle2D> dims = new ArrayList<Rectangle2D>(); for(LayoutContent fr: rects2){ dims.add(fr.mysize()); } int num = dims.size(); double parentrate = availableScreenSize.getWidth()/availableScreenSize.getHeight(); if (Double.isNaN(parentrate)) { parentrate = 1.66; } // System.out.println("LayoutAbst Parent "+parentrate); TreeMap<Double,Integer> resultRates = new TreeMap<Double,Integer>(); for(int i=1;i<=num;i++){ double fitrate = fitrateV(dims, i, xgap, ygap); resultRates.put(Math.abs(parentrate - fitrate), i); // System.out.println(i+"/"+num+" "+Math.abs(parentrate - fitrate)+" "+fitrate+" parent="+parentrate+" fitrateV"); } ArrayList<Integer> intres = new ArrayList<Integer>(resultRates.values()); if (intres.size()>0) rownum_or_colnum = intres.get(0); // System.out.println("LayAB 採用"+rownum_or_colnum); return rownum_or_colnum; } public double fitrateV(ArrayList<Rectangle2D> boxes, int varticalNum, double xgap, double ygap){ double x = 0, y = 0, w = 0, h = 0; int varticalCount = 0; for(Rectangle2D pn: boxes){ y += pn.getHeight() + ygap; if (x < pn.getWidth()) x = pn.getWidth(); varticalCount++; if (varticalCount == varticalNum){ w += x + xgap; if (h < y) h = y; varticalCount = 0; y = 0; x = 0; } } w += x + xgap; if (h < y) h = y; return w/h; } public double fitrateH(ArrayList<Rectangle2D> boxes, int horizontalNum, double xgap, double ygap){ double x = 0, y = 0, w = 0, h = 0; int horizonCount = 0; for(Rectangle2D pn: boxes){ x += pn.getWidth() + xgap; if (y < pn.getHeight()) y = pn.getHeight(); horizonCount++; if (horizonCount == horizontalNum){ h += y + ygap; if (w < x) w = x; horizonCount = 0; y = 0; x = 0; } } h += y + ygap; if (w < x) w = x; return w/h; } // public double fitrateHH(ArrayList<Rectangle2D> boxes, int horizontalNum, double xgap, double ygap){ // double x = 0, y = 0, w = 0, h = 0; // int horizonCount = 0; // // System.out.print("Try "+horizontalNum); // for(Rectangle2D pn: boxes){ // x += pn.getWidth() + xgap; // if (y < pn.getHeight()) y = pn.getHeight(); // horizonCount++; // if (horizonCount == horizontalNum){ // h += y + ygap; // if (w < x) w = x; // horizonCount = 0; // y = 0; // x = 0; // } // } // h += y + ygap; // if (w < x) w = x; // return w/h; // } }