/*
* Copyright (C) 2011 Alasdair C. Hamilton
*
* This program 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 3 of the License, or
* (at your option) any later version.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
*/
package ketUI.panel;
import geom.Offset;
import geom.Position;
import java.awt.*;
import java.util.*;
import ket.*;
import ket.math.*;
import ket.display.*;
import ket.display.box.Box;
import ket.display.box.BoxText;
/**
* Lists of equations may be displayed as a list that is aligned from the top,
* centre or bottom of the screen.
*/
public abstract class Align {
/**
* The fraction of each box's height that should be left as a gap
* between each equation and its neighbour.
*/
protected static final double FRACTIONAL_EQUATION_LIST_GAP = 1.0;
ListDisplay listDisplay;
/*
* As the height of each box is unknown until it is actually drawn by a
* callback method, all possible variations of the equation's location
* are stored.
*/
public Align(ListDisplay listDisplay) {
this.listDisplay = listDisplay;
}
protected abstract void moveViewUp();
protected abstract void moveViewDown();
/**
* Subclasses measure height in different ways and this method converts
* back to a measurement from the top of the ketPanel in which the
* equations are drawn.
* @param relativeHeight The arbitrary measure of height.
* @param totalPanelHeight The full height of the ketPanel in which the equations are drawn.
* @param boxIndex The i'th box is currently being drawn.
* @param equationShape The region in which the equation will be drawn
* which includes the outer rectangle for aligning the box and spacing
* between equations.
* @return The height of the box from the top of the ketPanel.
*/
protected abstract double getPanelHeightOfNextBox(
double relativeHeight,
double totalPanelHeight,
int boxIndex,
Offset equationShape);
public abstract Set<BoxEquation> paint(
Graphics2D g2D,
ColourScheme colourScheme,
int fontSize,
Offset panelRectangle);
protected void fromTop(int initialBoxIndex) {
listDisplay.fromTop(initialBoxIndex);
}
protected void fromMiddle(int middleBoxIndex) {
listDisplay.fromMiddle(middleBoxIndex);
}
protected void fromBottom(int bottomBoxIndex) {
listDisplay.fromBottom(bottomBoxIndex);
}
/**
* Convert the next equation into a box and from its height drawing it
* and returning its height, or -1 if there is not enough space left on
* the screen.
*/
protected double drawNextBoxWithLabel(
Graphics2D g2D,
ColourScheme colourScheme,
int fontSize,
double height,
Equation equation,
int boxIndex,
Offset panelRectangle,
Set<BoxEquation> set) {
// When sifting for specific equations, others are not displayed.
Vector<Equation> equations = listDisplay.getVisibleEquations();
//- if (equations!=null && !equations.contains(equation)) {
if (equations!=null && !equation.isIn(equations)) {
return 0.0;
}
Box box = equation.toBox(colourScheme);
// Determine the minimum size of the box and use a scaled value it to set its dimensions.
box.setupInnerRectangle(fontSize);
double minimumHeight = box.getInnerRectangle().height;
// TODO: Is this being done twice: here and in its parent or grandparent?
double shapeWidth = panelRectangle.width - KetPanel.LEFT_BORDER_SIZE - KetPanel.RIGHT_BORDER_SIZE;
Offset equationRectangle = new Offset(shapeWidth, FRACTIONAL_EQUATION_LIST_GAP*minimumHeight);
// Generate the label so as to have a size in order to avoid
// overlaps when drawing the rest of the equation.
Box labelBox = equation.getLabelBox(colourScheme);
labelBox.setProperty(Box.RIGHT_ALIGN);
labelBox.setProperty(Box.Y_CENTRE_ALIGN);
labelBox.setup(fontSize, equationRectangle);
// TODO: Distinguish between equationRectangle versions?
equationRectangle = new Offset(shapeWidth-labelBox.getInnerRectangle().width, FRACTIONAL_EQUATION_LIST_GAP*minimumHeight);
box.setupOuterRectangle(equationRectangle);
// NOTE: This over-generalizes box alignment by accepting box
// sizes beyond the given limit. This is an unfinished change,
// further extend it as appropriate.
// Note: this retains width but word wrap extends its depth.
equationRectangle = box.getOuterRectangle();
double panelHeightOfNextBox = getPanelHeightOfNextBox(height, panelRectangle.height, boxIndex, equationRectangle);
Position actualEquationTopLeft = new Position(KetPanel.LEFT_BORDER_SIZE, panelHeightOfNextBox);
if (height<=panelRectangle.height) {
BoxEquation boxEquation = new BoxEquation(box, labelBox, actualEquationTopLeft);
set.add(boxEquation);
return equationRectangle.height;
} else {
return -1.0;
}
}
public MathCollection getMathCollection() {
return listDisplay.getMathCollection();
}
protected int getNumberOfEquations() {
Selection selection = getMathCollection().getSelection();
return selection.getEquationList().size();
}
protected Equation getEquation(int index) {
Selection selection = getMathCollection().getSelection();
return selection.getEquationList().getEquation(index);
}
protected Vector<Equation> getSelectedEquations() {
return getMathCollection().getSelection().getSelectedEquations();
}
}