Copyright (C) 2000, 2001, Geert Vernaeve. All Rights Reserved.
package
gve.calc.formula;
import
java.awt.*;
import
awt.*;
import
awt.
Button
;
import
java.awt.event.*;
public
class
TabularView
extends
Container
implements
View
,
HasCursorPos
,
MouseSensitive
,
KeydnListener
,
CreatesPopup
{
private
Tabular
model;
Possible values: Somewhere_LEFT, Somewhere_RIGHT, 0 (off)
private
int
cursorPos;
public
TabularView
(
Tabular
model,
FormulaView
view) { this.model = model;
int
w = model.getWidth();
int
h = model.getHeight();
for
(
int
i = 0; i < h; i++) {
for
(
int
j = 0; j < w; j++) {
Part
p = model.elementAt(i,j); Component comp = view.getView(p); add(comp); } }
MVC
.registerView(model,this); setLayout(
new
TabularLayout
(h,w)); }
public
void
updateView(Object with) {
if
(with
instanceof
TabularModified
) {
TabularModified
mod = (
TabularModified
)with;
if
(mod.added) {
if
(mod.row) addRow(mod.i);
else
addCol(mod.i); }
else
{
// removed
// Must remove last elements first (else later elements shift back ...)
if
(mod.row) remRow(mod.i);
else
remCol(mod.i); } } }
public
void
remRow(
int
row) {
for
(
int
j = model.getWidth()-1; j>=0; j--) remove(j + model.getWidth() * row);
TabularLayout
layout = (
TabularLayout
)getLayout(); layout.setRows(model.getHeight()); }
public
void
remCol(
int
col) {
for
(
int
i = model.getHeight(); i>=0; i--) remove(col + model.getWidth() * i);
TabularLayout
layout = (
TabularLayout
)getLayout(); layout.setCols(model.getWidth()); }
public
void
addRow(
int
row) {
FormulaView
view =
FormulaView
.get(this);
for
(
int
j = 0; j < model.getWidth(); j++) add(view.getView(model.elementAt(row,j)),j + model.getWidth() * row);
TabularLayout
layout = (
TabularLayout
)getLayout(); layout.setRows(model.getHeight()); }
public
void
addCol(
int
col) {
FormulaView
view =
FormulaView
.get(this);
for
(
int
i = 0; i < model.getHeight(); i++) add(view.getView(model.elementAt(i,col)),col + model.getWidth() * i);
TabularLayout
layout = (
TabularLayout
)getLayout(); layout.setCols(model.getWidth()); }
public
Object getModel() {
return
model; }
public
void
activate() {}
public
void
deactivate() { cursorPos = 0; invalidate(); }
public
int
getCursorPos() {
return
cursorPos; }
public
void
setCursorPos(
int
pos) {
switch
(pos) {
case
Somewhere_LEFT:
case
Somewhere_RIGHT: cursorPos = pos;
break
;
default
: cursorPos = Somewhere_LEFT;
break
; } invalidate(); }
public
void
paint(Graphics g) {
super
.paint(g);
if
(cursorPos == Somewhere_LEFT) { FontMetrics fm = getFontMetrics(getFont());
int
fonth = fm.getHeight();
int
spatwidth = fm.charWidth(
' '
); Dimension siz = getSize(); g.fillRect(0,(siz.height - fonth)/2,spatwidth,fonth); }
else
if
(cursorPos == Somewhere_RIGHT) { FontMetrics fm = getFontMetrics(getFont());
int
fonth = fm.getHeight();
int
spatwidth = fm.charWidth(
' '
); Dimension siz = getSize(); g.fillRect(siz.width - spatwidth,(siz.height - fonth)/2,spatwidth,fonth); } }
public
boolean
mousePressed(
int
flags,
int
x,
int
y) {
return
false; }
public
void
mouseDown(
int
flags,
int
x,
int
y) { Dimension siz = getSize();
int
spatwidth = getFontMetrics(getFont()).charWidth(
' '
);
if
(x<siz.width/2 && x<spatwidth*2)
FormulaView
.get(this).setCursorComp(this,Somewhere_LEFT);
else
if
((siz.width-x)<siz.width/2 && (siz.width-x)<spatwidth*2)
FormulaView
.get(this).setCursorComp(this,Somewhere_RIGHT); }
public
Component createPopup(
int
x,
int
y) {
Button
b; TabularListener listen =
new
TabularListener(this,x,y); Container cont =
new
Panel(); cont.setLayout(
new
GridPackLayout
(0,1)); cont.add(b =
new
Button
(
"Insert row"
)); b.addActionListener(listen); cont.add(b =
new
Button
(
"Insert column"
)); b.addActionListener(listen);
return
cont; }
public
boolean
keydn(
int
key) {
FormulaView
view =
FormulaView
.get(this);
switch
(key) {
case
Key_LEFT:
if
(cursorPos == Somewhere_RIGHT) { view.setCursorPart(model.elementAt(0,model.getWidth()-1),Somewhere_RIGHT);
return
true; }
else
if
(cursorPos == 0) {
Part
p = view.getCursorPart(); Point which = model.whichOffspring(p);
if
(which.x > 0) view.setCursorPart(model.elementAt(which.y,which.x-1),Somewhere_RIGHT);
else
view.setCursorComp(this,Somewhere_LEFT);
return
true; }
return
false;
case
Key_RIGHT:
if
(cursorPos == Somewhere_LEFT) {
// Go to leftmost element of the table which is not an Uneditable
int
j = 0;
Part
p;
while
(true) { p = model.elementAt(0,j);
if
(!(p
instanceof
Uneditable
))
break
; j++; } view.setCursorPart(p,Somewhere_LEFT);
return
true; }
else
if
(cursorPos == 0) {
Part
p = view.getCursorPart(); Point which = model.whichOffspring(p);
if
(which.x+1 < model.getWidth()) view.setCursorPart(model.elementAt(which.y,which.x+1),Somewhere_LEFT);
else
view.setCursorComp(this,Somewhere_RIGHT);
return
true; }
return
false;
case
Key_UP:
if
(cursorPos == 0) {
Part
p = view.getCursorPart(); Point which = model.whichOffspring(p);
if
(which.y > 0) { view.setCursorPart(model.elementAt(which.y-1,which.x));
return
true; } }
return
false;
case
Key_DOWN:
if
(cursorPos == 0) {
Part
p = view.getCursorPart(); Point which = model.whichOffspring(p);
if
(which.y < model.getHeight()-1) { view.setCursorPart(model.elementAt(which.y+1,which.x));
return
true; } }
return
false;
case
Key_BS:
if
(cursorPos == Somewhere_RIGHT) {
// PENDING: register an Undo action
Formula
f = view.getFormula();
Part
empty; f.replace(model,empty =
new
Identifier
(
""
)); view.addUndoAction(
new
ReplaceUndo
(f,empty,model));
return
true; }
return
true;
case
Key_TAB:
if
(cursorPos == 0) { Point which = model.whichOffspring(view.getCursorPart());
// Find next element which is not Uneditable
while
(true) {
Part
p;
if
(which.x+1 < model.getWidth()) which.x++;
else
if
(which.y+1 < model.getHeight()) { which.x = 0; which.y++; }
else
return
false; p = model.elementAt(which.y,which.x);
if
(p
instanceof
Uneditable
)
continue
; view.setCursorPart(p,Somewhere_LEFT);
return
true; } }
return
false;
case
Key_SHTAB:
if
(cursorPos == 0) { Point which = model.whichOffspring(view.getCursorPart());
// Find next element which is not Uneditable
while
(true) {
Part
p;
if
(which.x > 0) which.x--;
else
if
(which.y > 0) { which.x = model.getWidth()-1; which.y--; }
else
return
false; p = model.elementAt(which.y,which.x);
if
(p
instanceof
Uneditable
)
continue
; view.setCursorPart(p,Somewhere_LEFT);
return
true; } }
return
false; }
// end case
if
(cursorPos == Somewhere_LEFT)
return
view.splitleft(model,key);
else
if
(cursorPos == Somewhere_RIGHT)
return
view.splitright(model,key);
return
false; }
public
void
insertColAtPixel(
int
xpixel) {
TabularLayout
layout = (
TabularLayout
)getLayout(); model.insertCol(layout.pixel2colBetween(xpixel)); }
public
void
insertRowAtPixel(
int
ypixel) {
TabularLayout
layout = (
TabularLayout
)getLayout(); model.insertRow(layout.pixel2rowBetween(ypixel)); } }
class
TabularListener
implements
ActionListener {
TabularView
tabview;
int
xpos,ypos;
// point of mouse click
public
TabularListener(
TabularView
m,
int
x,
int
y) { tabview = m; xpos = x; ypos = y; }
public
void
actionPerformed(ActionEvent evt) { String cmd = evt.getActionCommand();
if
(cmd.equals(
"Insert row"
)) { tabview.insertRowAtPixel(ypos); }
else
if
(cmd.equals(
"Insert column"
)) { tabview.insertColAtPixel(xpos); } } }