/********************************************************************************* * TotalCross Software Development Kit * * Copyright (C) 1998, 1999 Wabasoft <www.wabasoft.com> * * Copyright (C) 2000-2012 SuperWaba Ltda. * * All Rights Reserved * * * * This library and virtual machine is distributed in the hope that it will * * be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * * * This file is covered by the GNU LESSER GENERAL PUBLIC LICENSE VERSION 3.0 * * A copy of this license is located in file license.txt at the root of this * * SDK or can be downloaded here: * * http://www.gnu.org/licenses/lgpl-3.0.txt * * * *********************************************************************************/ package totalcross.ui; import totalcross.sys.*; /** This class is a Container that will place controls one after the other and, once the * width has been reached, it wraps to next line. * * Example: * <pre> * Settings.uiAdjustmentsBasedOnFontHeight = true; * * Label l = new Label("Do you agree that TotalCross is a great development platform?"); * l.autoSplit = true; * add(l, LEFT,AFTER,PARENTSIZE+100,PREFERRED); * * FlowContainer fc = new FlowContainer(50,25); * fc.add(new Radio("Probably Yes")); * fc.add(new Radio("Probably No")); * fc.add(new Radio("Maybe")); * add(fc, LEFT,AFTER,PARENTSIZE+100,PREFERRED); * </pre> * * All controls must be added before calling setRect. * * When calling setRect for this control, the height must be PREFERRED (with adjustments, if needed). * * Also, if initUI is overriden, be sure to call <code>super.initUI()</code>. * * <b>IT IS VERY IMPORTANT THAT YOU USE PARENTSIZE+100 INSTEAD OF FILL IN THE WIDTH PARAMETER!</b> * * @since TotalCross 1.39 */ public class FlowContainer extends Container { protected int lines = 1; private int hgap,vgap; private int lastASW; /** Constructs a FlowContainer with the given horizontal and vertical gaps. * You <b>must</b> add all children controls before calling setRect for this container. */ public FlowContainer(int hgap, int vgap) { this.hgap = hgap; this.vgap = vgap; } /** Places the controls on screen. */ public void initUI() { lines = 1; // position first control Control c = children; if (c == null) return; c.setRect(LEFT,TOP,PREFERRED,PREFERRED); int g = Settings.uiAdjustmentsBasedOnFontHeight && uiAdjustmentsBasedOnFontHeightIsSupported ? hgap*fmH/100 : hgap; // position next controls while (c != null) { int x2 = c.getX2()+g; c = c.next; if (c == null) break; c.resetSetPositions(); x2 += c.getPreferredWidth(); if (x2 <= width) // still fits in the same line? c.setRect(AFTER+hgap,SAME,PREFERRED,PREFERRED); else // wrap to new line { c.setRect(LEFT, AFTER+vgap, PREFERRED,PREFERRED); lines++; } } } protected void onBoundsChanged(boolean screenChanged) { if (setW == FILL) throw new RuntimeException("For FlowContainer subclasses, please use PARENTSIZE+100 instead of FILL"); if (this.width > 0 && this.width != lastASW && ((PREFERRED-RANGE) <= setH && setH <= (PREFERRED+RANGE))) { lastASW = this.width; initUI(); setRect(KEEP,KEEP,KEEP,getPreferredHeight() + setH-PREFERRED); } } public int getPreferredHeight() { int lines = 1; // position first control Control c = children; int g = Settings.uiAdjustmentsBasedOnFontHeight && uiAdjustmentsBasedOnFontHeightIsSupported ? hgap*fmH/100 : hgap; // position next controls int x2 = 0; while (c != null) { int w = c.getPreferredWidth()+g; x2 += w; c = c.next; if (x2 > tempW) // still fits in the same line? { lines++; x2 = w; } if (c == null) break; } return lines * (fmH+Edit.prefH) + getGap(vgap)*(lines-1); } }