| /* FrameSetView.java -- Implements HTML frameset | |
| Copyright (C) 2006 Free Software Foundation, Inc. | |
| This file is part of GNU Classpath. | |
| GNU Classpath is free software; you can redistribute it and/or modify | |
| it under the terms of the GNU General Public License as published by | |
| the Free Software Foundation; either version 2, or (at your option) | |
| any later version. | |
| GNU Classpath 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. See the GNU | |
| General Public License for more details. | |
| You should have received a copy of the GNU General Public License | |
| along with GNU Classpath; see the file COPYING. If not, write to the | |
| Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | |
| 02110-1301 USA. | |
| Linking this library statically or dynamically with other modules is | |
| making a combined work based on this library. Thus, the terms and | |
| conditions of the GNU General Public License cover the whole | |
| combination. | |
| As a special exception, the copyright holders of this library give you | |
| permission to link this library with independent modules to produce an | |
| executable, regardless of the license terms of these independent | |
| modules, and to copy and distribute the resulting executable under | |
| terms of your choice, provided that you also meet, for each linked | |
| independent module, the terms and conditions of the license of that | |
| module. An independent module is a module which is not derived from | |
| or based on this library. If you modify this library, you may extend | |
| this exception to your version of the library, but you are not | |
| obligated to do so. If you do not wish to do so, delete this | |
| exception statement from your version. */ | |
| package javax.swing.text.html; | |
| import java.util.StringTokenizer; | |
| import javax.swing.text.AttributeSet; | |
| import javax.swing.text.BoxView; | |
| import javax.swing.text.Element; | |
| import javax.swing.text.View; | |
| import javax.swing.text.ViewFactory; | |
| /** | |
| * Implements HTML framesets. This is implemented as a vertical box that | |
| * holds the rows of the frameset. Each row is again a horizontal box that | |
| * holds the actual columns. | |
| */ | |
| public class FrameSetView | |
| extends BoxView | |
| { | |
| /** | |
| * A row of a frameset. | |
| */ | |
| private class FrameSetRow | |
| extends BoxView | |
| { | |
| private int row; | |
| FrameSetRow(Element el, int r) | |
| { | |
| super(el, X_AXIS); | |
| row = r; | |
| } | |
| protected void loadChildren(ViewFactory f) | |
| { | |
| // Load the columns here. | |
| Element el = getElement(); | |
| View[] columns = new View[numViews[X_AXIS]]; | |
| int offset = row * numViews[X_AXIS]; | |
| for (int c = 0; c < numViews[X_AXIS]; c++) | |
| { | |
| Element child = el.getElement(offset + c); | |
| columns[c] = f.create(child); | |
| } | |
| replace(0, 0, columns); | |
| } | |
| protected void layoutMajorAxis(int targetSpan, int axis, int[] offsets, | |
| int[] spans) | |
| { | |
| int numRows = numViews[X_AXIS]; | |
| int[] abs = absolute[X_AXIS]; | |
| int[] rel = relative[X_AXIS]; | |
| int[] perc = percent[X_AXIS]; | |
| layoutViews(targetSpan, axis, offsets, spans, numRows, abs, rel, perc); | |
| } | |
| } | |
| /** | |
| * Holds the absolute layout information for the views along one axis. The | |
| * indices are absolute[axis][index], where axis is either X_AXIS (columns) | |
| * or Y_AXIS (rows). Rows or columns that don't have absolute layout have | |
| * a -1 in this array. | |
| */ | |
| int[][] absolute; | |
| /** | |
| * Holds the relative (*) layout information for the views along one axis. | |
| * The indices are relative[axis][index], where axis is either X_AXIS | |
| * (columns) or Y_AXIS (rows). Rows or columns that don't have relative | |
| * layout have a Float.NaN in this array. | |
| */ | |
| int[][] relative; | |
| /** | |
| * Holds the relative (%) layout information for the views along one axis. | |
| * The indices are relative[axis][index], where axis is either X_AXIS | |
| * (columns) or Y_AXIS (rows). Rows or columns that don't have relative | |
| * layout have a Float.NaN in this array. | |
| * | |
| * The percentage is divided by 100 so that we hold the actual fraction here. | |
| */ | |
| int[][] percent; | |
| /** | |
| * The number of children in each direction. | |
| */ | |
| int[] numViews; | |
| FrameSetView(Element el) | |
| { | |
| super(el, Y_AXIS); | |
| numViews = new int[2]; | |
| absolute = new int[2][]; | |
| relative = new int[2][]; | |
| percent = new int[2][]; | |
| } | |
| /** | |
| * Loads the children and places them inside the grid. | |
| */ | |
| protected void loadChildren(ViewFactory f) | |
| { | |
| parseRowsCols(); | |
| // Set up the rows. | |
| View[] rows = new View[numViews[Y_AXIS]]; | |
| for (int r = 0; r < numViews[Y_AXIS]; r++) | |
| { | |
| rows[r] = new FrameSetRow(getElement(), r); | |
| } | |
| replace(0, 0, rows); | |
| } | |
| /** | |
| * Parses the rows and cols attributes and sets up the layout info. | |
| */ | |
| private void parseRowsCols() | |
| { | |
| Element el = getElement(); | |
| AttributeSet atts = el.getAttributes(); | |
| String cols = (String) atts.getAttribute(HTML.Attribute.COLS); | |
| if (cols == null) // Defaults to '100%' when not specified. | |
| cols = "100%"; | |
| parseLayout(cols, X_AXIS); | |
| String rows = (String) atts.getAttribute(HTML.Attribute.ROWS); | |
| if (rows == null) // Defaults to '100%' when not specified. | |
| rows = "100%"; | |
| parseLayout(rows, Y_AXIS); | |
| } | |
| /** | |
| * Parses the cols or rows attribute and places the layout info in the | |
| * appropriate arrays. | |
| * | |
| * @param att the attributes to parse | |
| * @param axis the axis | |
| */ | |
| private void parseLayout(String att, int axis) | |
| { | |
| StringTokenizer tokens = new StringTokenizer(att, ","); | |
| numViews[axis] = tokens.countTokens(); | |
| absolute[axis] = new int[numViews[axis]]; | |
| relative[axis] = new int[numViews[axis]]; | |
| percent[axis] = new int[numViews[axis]]; | |
| for (int index = 0; tokens.hasMoreTokens(); index++) | |
| { | |
| String token = tokens.nextToken(); | |
| int p = token.indexOf('%'); | |
| int s = token.indexOf('*'); | |
| if (p != -1) | |
| { | |
| // Percent value. | |
| String number = token.substring(0, p); | |
| try | |
| { | |
| percent[axis][index] = Integer.parseInt(number); | |
| } | |
| catch (NumberFormatException ex) | |
| { | |
| // Leave value as 0 then. | |
| } | |
| } | |
| else if (s != -1) | |
| { | |
| // Star relative value. | |
| String number = token.substring(0, s); | |
| try | |
| { | |
| relative[axis][index] = Integer.parseInt(number); | |
| } | |
| catch (NumberFormatException ex) | |
| { | |
| // Leave value as 0 then. | |
| } | |
| } | |
| else | |
| { | |
| // Absolute value. | |
| try | |
| { | |
| absolute[axis][index] = Integer.parseInt(token); | |
| } | |
| catch (NumberFormatException ex) | |
| { | |
| // Leave value as 0 then. | |
| } | |
| } | |
| } | |
| } | |
| protected void layoutMajorAxis(int targetSpan, int axis, int[] offsets, | |
| int[] spans) | |
| { | |
| int numRows = numViews[Y_AXIS]; | |
| int[] abs = absolute[Y_AXIS]; | |
| int[] rel = relative[Y_AXIS]; | |
| int[] perc = percent[Y_AXIS]; | |
| layoutViews(targetSpan, axis, offsets, spans, numRows, abs, rel, perc); | |
| } | |
| void layoutViews(int targetSpan, int axis, int[] offsets, int[] spans, | |
| int numViews, int[] abs, int[] rel, int[] perc) | |
| { | |
| // We need two passes. In the first pass we layout the absolute and | |
| // percent values and accumulate the needed space. In the second pass | |
| // the relative values are distributed and the offsets are set. | |
| int total = 0; | |
| int relTotal = 0; | |
| for (int i = 0; i < numViews; i++) | |
| { | |
| if (abs[i] > 0) | |
| { | |
| spans[i] = abs[i]; | |
| total += spans[i]; | |
| } | |
| else if (perc[i] > 0) | |
| { | |
| spans[i] = (targetSpan * perc[i]) / 100; | |
| total += spans[i]; | |
| } | |
| else if (rel[i] > 0) | |
| { | |
| relTotal += rel[i]; | |
| } | |
| } | |
| int offs = 0; | |
| for (int i = 0; i < numViews; i++) | |
| { | |
| if (relTotal > 0 && rel[i] > 0) | |
| { | |
| spans[i] = targetSpan * (rel[i] / relTotal); | |
| } | |
| offsets[i] = offs; | |
| offs += spans[i]; | |
| } | |
| } | |
| } |