// (c): Asko Soukka /** * Cursor class especially designed for MM purposes. Could be * inherited from some more general class later on. */ package org.fenfire.fenmm; import org.nongnu.libvob.VobScene; import org.nongnu.libvob.TextStyle; import org.nongnu.libvob.vobs.LineVob; import org.nongnu.libvob.lava.placeable.TextPlaceable; import java.awt.Color; public class MMTextCursor { public static final String rcsid = ""; public static final float DEFAULT_SCALE = 1f; public static final Color DEFAULT_COLOR = Color.black; static class NotYetRenderedException extends Exception {} protected final Color color; protected final TextStyle style; protected final float scale; private Object accursed = null; private TextPlaceable p = null; private int offset = 0; private int length = 0; public MMTextCursor(TextStyle style, Color color, float scale) { this.color = color; this.style = style; this.scale = scale; } public MMTextCursor(TextStyle style, Color color) { this(style, color, DEFAULT_SCALE); } public MMTextCursor(TextStyle style) { this(style, DEFAULT_COLOR, DEFAULT_SCALE); } public void setAccursed(Object node) { accursed = node; offset = 0; } public Object getAccursed() { return accursed; } public int setOffset(int offset) { this.offset = offset; return this.offset; } public int setOffset(float x, float y) throws NotYetRenderedException { if (p == null) throw new NotYetRenderedException(); offset = p.getCursorPos(x, y); return offset; } public int getOffset() { return offset; } /** Move the cursor a character to the left. */ public int moveLeft() { if (offset > 0) offset -= 1; return offset; } /** Move the cursor a character to the right. */ public int moveRight() throws NotYetRenderedException { if (p == null) throw new NotYetRenderedException(); if (length == 0) length = getLength(); if (offset < length) offset += 1; return offset; } /** Move the cursor to the previous line. */ public int moveUp() throws NotYetRenderedException { if (p == null) throw new NotYetRenderedException(); float cursorXY[] = new float[2]; p.getCursorXY(offset, cursorXY); cursorXY[1] -= style.getHeight(scale); offset = p.getCursorPos(cursorXY[0], cursorXY[1]); return offset; } /** Move the cursor to the next line. */ public int moveDown() throws NotYetRenderedException { if (p == null) throw new NotYetRenderedException(); float cursorXY[] = new float[2]; p.getCursorXY(offset, cursorXY); cursorXY[1] += style.getHeight(scale); offset = p.getCursorPos(cursorXY[0], cursorXY[1]); return offset; } /** Move the cursor into the beginning of the text. */ public int moveBegin() { offset = 0; return offset; } /** Move the cursor to the end of the text. */ public int moveEnd() throws NotYetRenderedException { if (p == null) throw new NotYetRenderedException(); if (length == 0) length = getLength(); offset = length; return offset; } /** Move the cursor into the beginning of the line. */ public int moveBeginLine() throws NotYetRenderedException{ if (p == null) throw new NotYetRenderedException(); float cursorXY[] = new float[2]; p.getCursorXY(offset, cursorXY); cursorXY[0] = 0; offset = p.getCursorPos(cursorXY[0], cursorXY[1]); return offset; } /** Move the cursor to the end of the line. */ public int moveEndLine() throws NotYetRenderedException { if (p == null) throw new NotYetRenderedException(); if (length == 0) length = getLength(); // the end of line is reached by going to home of the line below // and returning a single character back if not the end of text was reached float cursorXY[] = new float[2]; p.getCursorXY(offset, cursorXY); cursorXY[0] = 0; cursorXY[1] += style.getHeight(scale); offset = p.getCursorPos(cursorXY[0], cursorXY[1]); if (offset < length) offset -= 1; return offset; } /** Way to use without rendering. */ public void setTextPlaceable(TextPlaceable p) { this.p = p; this.length = 0; } public void render(VobScene vs, int rootCS, TextPlaceable p) { setTextPlaceable(p); int nodeCS = vs.matcher.getCS(accursed); float nodeXY[] = {0f, 0f, 0f}; vs.coords.transformPoints3(nodeCS, nodeXY, nodeXY); float cursorXY[] = new float[2]; this.p.getCursorXY(offset, cursorXY); int cursorCS = vs.orthoCS(rootCS, "CURSOR", -1000, nodeXY[0] + cursorXY[0], nodeXY[1] + cursorXY[1], 1, -style.getHeight(scale)); vs.put(new LineVob(0,0,0,1, color), cursorCS); } private int getLength() throws NotYetRenderedException { if (p == null) throw new NotYetRenderedException(); return p.getCursorPos(p.getWidth(), p.getHeight()); } }