/*
* 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 java.net.URL;
import java.awt.*;
import java.util.*;
import javax.swing.JPanel;
import java.awt.geom.AffineTransform;
import geom.Offset;
import geom.Position;
import ket.*;
import ket.display.*;
import ket.display.box.BorderedBox;
import ket.display.box.Box;
import ket.display.box.BoxList;
import ket.display.box.BoxText;
import ket.display.box.BoxTools;
import ket.display.box.BoxWord;
import ket.math.*;
import ket.math.purpose.Word;
import ketUI.*;
import ketUI.Document;
import ketUI.Ket;
import ketUI.MouseEventHandler;
import ketUI.chord.Chord;
import ketUI.chord.KeyboardEventHandler;
import ketUI.modes.*;
import ketUI.responder.*;
/**
* Various bits of information are displayed on the KetPanel which are handled by this class.
*/
public class PanelDecoration {
public static final Token KET_PANEL = new Token(new Word("KetPanel"));
public static final Token MESSAGE = new Token(new Word("Message"));
public static final Token MODE = new Token(new Word("Mode"));
final Document document;
final ScrollBar scrollBar;
BoxList messageBoxList;
Box messageBox;
Box modeBox;
public PanelDecoration(Document document) {
this.document = document;
this.scrollBar = new ScrollBar(document);
messageBoxList = null;
messageBox = null;
modeBox = null;
}
public BoxList getMessageBoxList() {
return messageBoxList;
}
public void updateMessageBox() {
Message message = getModes().getMessage();
String messageString = message.getLine();
String startString = " " + message.getStart();
String endString = message.getEnd() + " ";
ColourScheme colourScheme = (ColourScheme) document.getColourScheme();
Color selectedColour = colourScheme.getHighlightedColour(0);
Color backgroundColour = colourScheme.getBackgroundColour();
// text colour: highlight ? selectedColour : backgroundColour;
BoxWord startBoxWord = new BoxWord(KET_PANEL, startString, 0L);
BoxWord endBoxWord = new BoxWord(KET_PANEL, endString, 0L);
if (getModes().getDocumentState()==DocumentState.UPDATE_TEXT) {
// Text doesn't require a separate message box.
this.messageBoxList = null;
this.messageBox = null;
} else if (message.getMode()==Message.APPEND_MODE) {
// WARNING: Message box's contents can't be found with findDeepestArgument() if they have a null argument.
BoxWord gapBox = new BoxWord(KET_PANEL, "|", 0L);
messageBoxList = BoxTools.centredHorizontalBoxList(KET_PANEL, 0L, startBoxWord, gapBox, endBoxWord);
//- messageBox = new BorderedBox(MESSAGE, messageBoxList, Box.X_CENTRE_ALIGN|Box.BOTTOM_ALIGN, false, colourScheme.getPlainTextColour(), colourScheme);
messageBox = new BorderedBox(MESSAGE, messageBoxList, Box.X_CENTRE_ALIGN|Box.BOTTOM_ALIGN, false, colourScheme);
} else if (messageString.length()>0) { // Echo and error modes.
// TODO: Don't display the cursor in error or echo responder: only in edit responder.
messageBoxList = BoxTools.centredHorizontalBoxList(MESSAGE, 0L, startBoxWord, endBoxWord);
//- messageBox = new BorderedBox(MESSAGE, messageBoxList, Box.X_CENTRE_ALIGN|Box.BOTTOM_ALIGN, false, colourScheme.getPlainTextColour(), colourScheme);
messageBox = new BorderedBox(MESSAGE, messageBoxList, Box.X_CENTRE_ALIGN|Box.BOTTOM_ALIGN, false, colourScheme);
} else {
this.messageBoxList = null;
this.messageBox = null;
}
}
public void updateModeLabel() {
DocumentState ds = getModes().getDocumentState();
if (ds==null) {
return;
}
String modeString = ds.getLabel();
if (modeString==null) {
// Don't display a mode in ECHO_MODE/VIEW
this.modeBox = null;
return;
}
ColourSchemeDecorator colourScheme = document.getColourScheme();
MathCollection mc = document.getMathCollection();
if (mc.isRangeSelectionSet()) {
modeString = "*" + modeString + "*";
} else if (mc.isColumnSelectionSet()) {
modeString = "|" + modeString + "|";
}
this.modeBox = new BoxText(MODE, modeString, Box.BOLD_FONT);
String details = ds.getDetails(); // An optional sub-heading to the label.
if (details!=null) {
Box detailsBox = new BoxText(MODE, details, 0L); // Subscript?
this.modeBox = BoxTools.centredVerticalBoxList(MODE, 0L, this.modeBox, detailsBox);
}
this.modeBox = new BorderedBox(MODE, this.modeBox, Box.RIGHT_ALIGN|Box.BOTTOM_ALIGN, false, colourScheme);
}
public void paint(Graphics2D g2D, Offset drawRectangle, ColourScheme colourScheme) {
if (modeBox!=null) {
modeBox.setupAndPaint(g2D, colourScheme, Box.DEFAULT_BOX_FONT_SIZE, KetPanel.TOP_LEFT_BORDER, drawRectangle, false);
}
if (messageBox!=null) {
messageBox.setupAndPaint(g2D, colourScheme, Box.DEFAULT_BOX_FONT_SIZE, KetPanel.TOP_LEFT_BORDER, drawRectangle, false);
}
if (getModes().getDocumentState()!=DocumentState.ECHO_VIEW) {
scrollBar.paint(g2D);
}
}
public void update() {
updateModeLabel();
updateMessageBox();
}
// --- HELPER METHODS ---
public Modes getModes() {
return document.getModes();
}
private int getFontSize() {
// WARNING: The panel decoration scales more slowely than large equations.
return (document.getBoxFontSize() + 2*Box.DEFAULT_BOX_FONT_SIZE) / 3;
}
private ColourScheme getColourScheme() {
return document.getColourScheme();
}
public ScrollBar getScrollBar() {
return scrollBar;
}
public double getModeBoxHeight() {
if (modeBox==null) return 0.0;
Offset inner = modeBox.getInnerRectangle();
if (inner==null) return 0.0;
return inner.height;
}
}