created mirror
This commit is contained in:
134
Java/flob/ArrowDecor.java
Normal file
134
Java/flob/ArrowDecor.java
Normal file
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
ArrwDecor.java
|
||||
*
|
||||
* Copyright (c) 2000, Ted Nelson and Tuomas Lukka
|
||||
*
|
||||
* You may use and distribute under the terms of either the GNU Lesser
|
||||
* General Public License, either version 2 of the license or,
|
||||
* at your choice, any later version. Alternatively, you may use and
|
||||
* distribute under the terms of the XPL.
|
||||
*
|
||||
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
|
||||
* the licenses.
|
||||
*
|
||||
* This software 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 README
|
||||
* file for more details.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Written by Tuomas Lukka
|
||||
*/
|
||||
|
||||
package org.gzigzag;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.util.*;
|
||||
|
||||
/** Arrows.
|
||||
*/
|
||||
|
||||
public class ArrowDecor extends CoordDecor {
|
||||
public static final String rcsid = "$Id: ArrowDecor.java,v 1.4 2000/10/26 18:09:29 tjl Exp $";
|
||||
public static final boolean dbg = false;
|
||||
static final void p(String s) { if(dbg) System.out.println(s); }
|
||||
static final void pa(String s) { System.out.println(s); }
|
||||
|
||||
Color color;
|
||||
|
||||
/** A simple class that knows how to efficiently build
|
||||
* ArrowDecors.
|
||||
*/
|
||||
static public class Builder extends CoordDecor.Builder {
|
||||
Color col;
|
||||
public Builder(FlobSet into, Color col) {
|
||||
super(into);
|
||||
this.col = col;
|
||||
}
|
||||
/** Make a line.
|
||||
*/
|
||||
public final void ar(int x0, int y0, int x1, int y1) {
|
||||
makeRoom(4);
|
||||
p[curp] = x0;
|
||||
p[curp+1] = y0;
|
||||
p[curp+2] = x1;
|
||||
p[curp+3] = y1;
|
||||
curp += 4;
|
||||
}
|
||||
protected Renderable create() {
|
||||
return new ArrowDecor(p, np, col, d);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public ArrowDecor(int[] coords, int n, int d) {
|
||||
this(coords, n, null, d);
|
||||
}
|
||||
|
||||
/** Usual constructor.
|
||||
* @param coords The coordinates for the lines, given as
|
||||
* quadruplets x1, y1, x2, y2.
|
||||
*/
|
||||
public ArrowDecor(int[] coords, int n, Color color, int d) {
|
||||
super(coords, n, d);
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
public ArrowDecor(int x1, int y1, int x2, int y2, Color color, int d) {
|
||||
super(null, 4, d);
|
||||
this.coords = new int[] {
|
||||
x1, y1, x2, y2
|
||||
};
|
||||
this.color = color;
|
||||
this.d = d;
|
||||
}
|
||||
|
||||
public void render(Graphics g) {
|
||||
Color old = null;
|
||||
if(color != null) {
|
||||
old = g.getColor();
|
||||
g.setColor(color);
|
||||
}
|
||||
|
||||
for(int i=0; i+3<n; i+=4) {
|
||||
int x1 = coords[i]; int y1=coords[i+1];
|
||||
int x2 = coords[i+2]; int y2=coords[i+3];
|
||||
|
||||
int dx = x2 - x1;
|
||||
int dy = y2 - y1;
|
||||
int ox = -dy;
|
||||
int oy = dx;
|
||||
int [] x = new int[] {
|
||||
x1 + ox/3 - dx/3,
|
||||
x1 + ox/6 + (3*dx)/5,
|
||||
x1 + ox/2 + (2*dx)/5,
|
||||
x1 + dx,
|
||||
x1 - ox/2 + (2*dx)/5,
|
||||
x1 - ox/6 + (3*dx)/5,
|
||||
x1 - ox/3 - dx/3,
|
||||
x1
|
||||
};
|
||||
int [] y = new int[] {
|
||||
y1 + oy/3 - dy/3,
|
||||
y1 + oy/6 + (3*dy)/5,
|
||||
y1 + oy/2 + (2*dy)/5,
|
||||
y1 + dy,
|
||||
y1 - oy/2 + (2*dy)/5,
|
||||
y1 - oy/6 + (3*dy)/5,
|
||||
y1 - oy/3 - dy/3,
|
||||
y1
|
||||
};
|
||||
Color c = g.getColor();
|
||||
g.setColor(color);
|
||||
g.fillPolygon(x, y, x.length);
|
||||
g.setColor(c);
|
||||
g.drawPolyline(x, y, x.length-1);
|
||||
|
||||
}
|
||||
|
||||
if(old != null)
|
||||
g.setColor(old);
|
||||
}
|
||||
|
||||
}
|
||||
159
Java/flob/BallCell.java
Normal file
159
Java/flob/BallCell.java
Normal file
@@ -0,0 +1,159 @@
|
||||
/*
|
||||
BallCell.java
|
||||
*
|
||||
* Copyright (c) 1999-2000, Ted Nelson and Tuomas Lukka
|
||||
*
|
||||
* You may use and distribute under the terms of either the GNU Lesser
|
||||
* General Public License, either version 2 of the license or,
|
||||
* at your choice, any later version. Alternatively, you may use and
|
||||
* distribute under the terms of the XPL.
|
||||
*
|
||||
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
|
||||
* the licenses.
|
||||
*
|
||||
* This software 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 README
|
||||
* file for more details.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Written by Tuomas Lukka
|
||||
*/
|
||||
|
||||
package org.gzigzag;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.util.*;
|
||||
|
||||
/** A ball-and-stick graphical representation of a cell.
|
||||
*/
|
||||
|
||||
public class BallCell extends Flob implements Colorer {
|
||||
public static final String rcsid = "$Id: BallCell.java,v 1.1.10.1 2002/02/16 18:51:42 tuukkah Exp $";
|
||||
public static final boolean dbg = true;
|
||||
|
||||
String s;
|
||||
Font f;
|
||||
// XXX Should this *really* need to be stored here?
|
||||
FontMetrics fm;
|
||||
|
||||
/** Font height. */
|
||||
int fh;
|
||||
int fasc;
|
||||
/** String width. */
|
||||
int sw;
|
||||
|
||||
ZZCell strCell;
|
||||
|
||||
int xoffs = 3;
|
||||
int yoffs = 3;
|
||||
|
||||
Color ballColor;
|
||||
Color bgColor;
|
||||
|
||||
public boolean addColor(Color c) {
|
||||
if(ballColor == null) ballColor = c;
|
||||
return true;
|
||||
}
|
||||
|
||||
static public final Dimension getSize(FontMetrics fm, String str,
|
||||
int xoffs, int yoffs) {
|
||||
int w = fm.stringWidth(str) + xoffs * 2 + 2;
|
||||
int h = fm.getHeight() + 2*yoffs;
|
||||
w += h; // Room for the ball.
|
||||
return new Dimension( w, h );
|
||||
}
|
||||
|
||||
public int getStrX(int ind) {
|
||||
if(fm == null) throw new Error("No fontmetrics");
|
||||
if(ind > s.length()) {
|
||||
// XXX What to do?
|
||||
return x + xoffs + h + fm.stringWidth(s);
|
||||
}
|
||||
return x + xoffs + h + fm.stringWidth(s.substring(0, ind)) ;
|
||||
}
|
||||
|
||||
public void render(Graphics g, int mx, int my, int md,
|
||||
int mw, int mh) {
|
||||
int ty = my + (mh-fh)/2 + fasc;
|
||||
Color bu = g.getColor();
|
||||
g.setColor(ballColor != null ? ballColor : Color.white);
|
||||
g.fillOval(mx+yoffs, my+yoffs, mh-2*yoffs, mh-2*yoffs);
|
||||
g.setFont(f);
|
||||
int start = 0;
|
||||
int end = -1;
|
||||
while (end < s.length()) { // Split into lines
|
||||
|
||||
do {
|
||||
end = s.indexOf(' ', end + 1);
|
||||
if (end == -1) break;
|
||||
} while (fm.stringWidth(s.substring(start, end)) < mw);
|
||||
|
||||
if (end == -1)
|
||||
end = s.length();
|
||||
if (start < end) {
|
||||
String line = s.substring(start, end);
|
||||
|
||||
g.setColor(bgColor);
|
||||
if (false && start != 0) {
|
||||
g.fillRect(mx+xoffs + h - 2, ty - (fasc - (fh-fasc)), fm.stringWidth(line), fasc-(fh-fasc));
|
||||
} else {
|
||||
g.drawString(line, mx+xoffs + h - 1, ty - 1);
|
||||
g.drawString(line, mx+xoffs + h + 2, ty + 2);
|
||||
}
|
||||
|
||||
g.setColor(Color.white);
|
||||
g.drawString(line, mx+xoffs + h + 1, ty + 1);
|
||||
|
||||
g.setColor(bu);
|
||||
g.drawString(line, mx+xoffs + h, ty);
|
||||
ty += fasc;
|
||||
}
|
||||
start = end + 1;
|
||||
}
|
||||
|
||||
g.setColor(bu);
|
||||
g.drawOval(mx+yoffs, my+yoffs, mh-2*yoffs, mh-2*yoffs);
|
||||
}
|
||||
|
||||
public BallCell(int x, int y, int d, int w, int h,
|
||||
ZZCell c, ZZCell strCell, String s,
|
||||
Font f, FontMetrics fm, FlobSet fs) {
|
||||
super(x, y, d, w, h, c);
|
||||
|
||||
// Not true, since c can be the flob cell and d the referring
|
||||
// cell.
|
||||
// this.s = c.getText();
|
||||
|
||||
this.s = (s==null? "" : s);
|
||||
this.strCell = strCell;
|
||||
|
||||
this.f = f;
|
||||
this.fm = fm;
|
||||
|
||||
this.fh = fm.getAscent()+fm.getDescent();
|
||||
this.fasc = fm.getAscent()+fm.getLeading();
|
||||
this.sw = fm.stringWidth(this.s);
|
||||
|
||||
this.bgColor = fs.getBackground();
|
||||
}
|
||||
|
||||
public Object hit(int x0, int y0) {
|
||||
if(!insideRect(x0, y0)) return null;
|
||||
// Search for the right position in the string.
|
||||
// We return a virtual cursor.
|
||||
int ind = ZZUtil.findStringHit(s, x0-x-xoffs-h, fm);
|
||||
|
||||
return new ZZCursorVirtual(strCell, ind);
|
||||
}
|
||||
|
||||
public Point getCenter(Point p) {
|
||||
p.x = x + h/2;
|
||||
p.y = y + h/2;
|
||||
return p;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
107
Java/flob/BeamDecor.java
Normal file
107
Java/flob/BeamDecor.java
Normal file
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
BeamDecor.java
|
||||
*
|
||||
* Copyright (c) 2000, Ted Nelson and Tuomas Lukka
|
||||
*
|
||||
* You may use and distribute under the terms of either the GNU Lesser
|
||||
* General Public License, either version 2 of the license or,
|
||||
* at your choice, any later version. Alternatively, you may use and
|
||||
* distribute under the terms of the XPL.
|
||||
*
|
||||
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
|
||||
* the licenses.
|
||||
*
|
||||
* This software 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 README
|
||||
* file for more details.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Written by Tuomas Lukka
|
||||
*/
|
||||
|
||||
package org.gzigzag;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.util.*;
|
||||
|
||||
/** A class for drawing beam decorations.
|
||||
* Beams are currently irregular octagons.
|
||||
* NOTE: Beams are rendered in reverse order: the first beam put in here
|
||||
* becomes the topmost.
|
||||
*/
|
||||
|
||||
public class BeamDecor extends CoordDecor {
|
||||
public static final String rcsid = "$Id: BeamDecor.java,v 1.4 2000/09/19 10:31:59 ajk Exp $";
|
||||
public static boolean dbg = false;
|
||||
static void p(String s) { if(dbg) System.out.println(s); }
|
||||
static void pa(String s) { System.out.println(s); }
|
||||
|
||||
Color[] colors;
|
||||
|
||||
/** A simple class that knows how to efficiently build
|
||||
* these things.
|
||||
*/
|
||||
static public class Builder extends CoordDecor.Builder {
|
||||
Color []col;
|
||||
public Builder(FlobSet into) {
|
||||
super(into);
|
||||
}
|
||||
|
||||
protected void makeRoom(int l) {
|
||||
if(col != null && nth >= col.length)
|
||||
endl();
|
||||
super.makeRoom(l);
|
||||
}
|
||||
|
||||
protected void alloc() {
|
||||
super.alloc();
|
||||
col = new Color[np/16];
|
||||
}
|
||||
/** Make a beam.
|
||||
* Coords: first 8x, then 8y.
|
||||
*/
|
||||
public final void b(int []xy, Color c) {
|
||||
makeRoom(16);
|
||||
p("beam: "+p+" "+col+" "+curp+" "+nth);
|
||||
for(int i=0; i<16; i++)
|
||||
p[curp+i] = xy[i];
|
||||
col[nth] = c;
|
||||
curp += 16;
|
||||
nth++;
|
||||
}
|
||||
protected Renderable create() {
|
||||
Color[] col2 = col;
|
||||
col = null;
|
||||
return new BeamDecor(p, np, d, col2);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public BeamDecor(int[] coords, int n, int d, Color[] cols) {
|
||||
super(coords, n, d);
|
||||
this.colors = cols;
|
||||
}
|
||||
|
||||
|
||||
public void render(Graphics g) {
|
||||
Color old = null;
|
||||
old = g.getColor();
|
||||
|
||||
int[] x = new int[8];
|
||||
int[] y = new int[8];
|
||||
for(int i=(n-16)-n%16; i>=0; i-=16) {
|
||||
for(int k = 0; k<8; k++)
|
||||
x[k] = coords[i+k];
|
||||
for(int k = 0; k<8; k++)
|
||||
y[k] = coords[i+8+k];
|
||||
|
||||
g.setColor(colors[i/16]);
|
||||
g.fillPolygon(x, y, 8);
|
||||
}
|
||||
|
||||
g.setColor(old);
|
||||
}
|
||||
|
||||
}
|
||||
90
Java/flob/BoxType.java
Normal file
90
Java/flob/BoxType.java
Normal file
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
BoxType.java
|
||||
*
|
||||
* Copyright (c) 2001, Ted Nelson and Tuomas Lukka
|
||||
* Copyright (c) 2001, Benja Fallenstein
|
||||
*
|
||||
* You may use and distribute under the terms of either the GNU Lesser
|
||||
* General Public License, either version 2 of the license or,
|
||||
* at your choice, any later version. Alternatively, you may use and
|
||||
* distribute under the terms of the XPL.
|
||||
*
|
||||
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
|
||||
* the licenses.
|
||||
*
|
||||
* This software 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 README
|
||||
* file for more details.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Written by Benja Fallenstein
|
||||
*/
|
||||
|
||||
package org.gzigzag;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.util.*;
|
||||
|
||||
/** A type of boxes to be drawn around vobs (like the CellBgFlob backgrounds).
|
||||
* Default: render nothing.
|
||||
*/
|
||||
|
||||
public class BoxType {
|
||||
public static final String rcsid = "$Id: BoxType.java,v 1.2 2001/03/18 17:50:16 bfallenstein Exp $";
|
||||
public static final boolean dbg = true;
|
||||
static final void p(String s) { if(dbg) System.out.println(s); }
|
||||
static final void pa(String s) { System.out.println(s); }
|
||||
|
||||
protected Color bg = Color.white;
|
||||
public void setBg(Color c) { if( c != null ) bg = c; }
|
||||
|
||||
protected void renderBg(Graphics g, BoxedFlob f, int mx, int my,
|
||||
int md, int mw, int mh) {}
|
||||
|
||||
protected void renderFrame(Graphics g, BoxedFlob f, int mx, int my,
|
||||
int md, int mw, int mh) {}
|
||||
|
||||
/** Render the background behind the flob.
|
||||
*/
|
||||
public void renderBg(Graphics g, Flob f) {
|
||||
renderBg(g, (BoxedFlob)f, f.x, f.y, f.d, f.w, f.h);
|
||||
}
|
||||
|
||||
/** Render the frame around the flob.
|
||||
*/
|
||||
public void renderFrame(Graphics g, Flob f) {
|
||||
renderFrame(g, (BoxedFlob)f, f.x, f.y, f.d, f.w, f.h);
|
||||
}
|
||||
|
||||
/** Render the interpolated background behind the flob.
|
||||
*/
|
||||
public void renderBg(Graphics g, Flob f, float fract) {
|
||||
// XXX the interpolation path isn't necessarily linear!
|
||||
Flob r = f.interpTo;
|
||||
renderBg(g, (BoxedFlob)f,
|
||||
(int)(f.x + fract*(r.x-f.x)),
|
||||
(int)(f.y + fract*(r.y-f.y)),
|
||||
(int)(f.d + fract*(r.d-f.d)),
|
||||
(int)(f.w + fract*(r.w-f.w)),
|
||||
(int)(f.h + fract*(r.h-f.h))
|
||||
);
|
||||
}
|
||||
|
||||
/** Render the interpolated frame around the flob.
|
||||
*/
|
||||
public void renderFrame(Graphics g, Flob f, float fract) {
|
||||
// XXX the interpolation path isn't necessarily linear!
|
||||
Flob r = f.interpTo;
|
||||
renderFrame(g, (BoxedFlob)f,
|
||||
(int)(f.x + fract*(r.x-f.x)),
|
||||
(int)(f.y + fract*(r.y-f.y)),
|
||||
(int)(f.d + fract*(r.d-f.d)),
|
||||
(int)(f.w + fract*(r.w-f.w)),
|
||||
(int)(f.h + fract*(r.h-f.h))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
83
Java/flob/BoxedFlob.java
Normal file
83
Java/flob/BoxedFlob.java
Normal file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
BoxedFlob.java
|
||||
*
|
||||
* Copyright (c) 2001, Ted Nelson and Tuomas Lukka
|
||||
* Copyright (c) 2001, Benja Fallenstein
|
||||
*
|
||||
* You may use and distribute under the terms of either the GNU Lesser
|
||||
* General Public License, either version 2 of the license or,
|
||||
* at your choice, any later version. Alternatively, you may use and
|
||||
* distribute under the terms of the XPL.
|
||||
*
|
||||
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
|
||||
* the licenses.
|
||||
*
|
||||
* This software 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 README
|
||||
* file for more details.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Written by Tuomas Lukka, adapted by Benja Fallenstein
|
||||
*/
|
||||
|
||||
package org.gzigzag;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.util.*;
|
||||
|
||||
/** A flob which gets rendered by FlobSet with a background.
|
||||
* XXX support for different shapes than rectangular?
|
||||
* XXX replace Colorer entirely by this?
|
||||
* XXX renderer must know whether background is transparent!
|
||||
* XXX move needsBox here and default to true?!? replace by instanceof Boxed?
|
||||
*/
|
||||
|
||||
public class BoxedFlob extends Flob implements Colorer {
|
||||
public static final String rcsid = "$Id: BoxedFlob.java,v 1.1 2001/03/20 11:08:36 ajk Exp $";
|
||||
public static final boolean dbg = true;
|
||||
// static final void p(String s) { if(dbg) System.out.println(s); }
|
||||
// static final void pa(String s) { System.out.println(s); }
|
||||
|
||||
// XXX need this? boolean drawBorder = true;
|
||||
|
||||
public boolean needsBox() { return true; }
|
||||
|
||||
int nsolids = 0;
|
||||
Color[] solids;
|
||||
protected Color bg = Color.white;
|
||||
|
||||
public Object hit(int x0, int y0) {
|
||||
if( x0 >= x && y0 >= y && x0 < x+w && y0 < y+h )
|
||||
return c;
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setBg(Color c){ if( c != null ) bg = c; }
|
||||
|
||||
/** Adds one more solid color to be drawn inside
|
||||
* the cell.
|
||||
*/
|
||||
public boolean addColor(Color c) {
|
||||
if(solids == null || nsolids >= solids.length) {
|
||||
Color[] n= new Color[nsolids + 10];
|
||||
if(solids != null) System.arraycopy(solids, 0, n, 0, nsolids);
|
||||
solids = n;
|
||||
}
|
||||
solids[nsolids++] = c;
|
||||
return false;
|
||||
}
|
||||
/** The currently put solid colors.
|
||||
* null = none. There may be null references near the end
|
||||
* of the array. Mostly useful for checking for nullness.
|
||||
*/
|
||||
public Color[] getSolidColors() { return solids; }
|
||||
|
||||
public BoxedFlob(int x, int y, int d, int w, int h,
|
||||
ZZCell c) {
|
||||
super(x, y, d, w, h, c);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
118
Java/flob/CellBgFlob.java
Normal file
118
Java/flob/CellBgFlob.java
Normal file
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
CellBgFlob.java
|
||||
*
|
||||
* Copyright (c) 1999-2000, Ted Nelson and Tuomas Lukka
|
||||
*
|
||||
* You may use and distribute under the terms of either the GNU Lesser
|
||||
* General Public License, either version 2 of the license or,
|
||||
* at your choice, any later version. Alternatively, you may use and
|
||||
* distribute under the terms of the XPL.
|
||||
*
|
||||
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
|
||||
* the licenses.
|
||||
*
|
||||
* This software 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 README
|
||||
* file for more details.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Written by Tuomas Lukka
|
||||
*/
|
||||
|
||||
package org.gzigzag;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.util.*;
|
||||
|
||||
/** A flob for the cell background.
|
||||
* Draws a filled (possibly with several colors) background rectangle,
|
||||
* surrounded by a rectangle of the current foreground color.
|
||||
*/
|
||||
|
||||
public class CellBgFlob extends Flob implements Colorer {
|
||||
public static final String rcsid = "$Id: CellBgFlob.java,v 1.16 2001/02/26 18:03:29 raulir Exp $";
|
||||
public static final boolean dbg = true;
|
||||
static final void p(String s) { if(dbg) System.out.println(s); }
|
||||
static final void pa(String s) { System.out.println(s); }
|
||||
|
||||
boolean drawBorder = true;
|
||||
|
||||
int nsolids = 0;
|
||||
Color[] solids;
|
||||
protected Color bg = Color.white;
|
||||
|
||||
public Object hit(int x0, int y0) {
|
||||
if( x0 >= x && y0 >= y && x0 < x+w && y0 < y+h )
|
||||
return c;
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setBg(Color c){ if( c != null ) bg = c; }
|
||||
|
||||
/** Override this in subclasses to render something inside the cell.
|
||||
*/
|
||||
protected void renderContent(Graphics g, int mx, int my, int mw, int mh) {
|
||||
}
|
||||
|
||||
public void render(Graphics g, int mx, int my, int md, int mw, int mh) {
|
||||
|
||||
// p("ZZCC1 render: "+g+" "+mx+" "+my+" "+mw+" "+mh);
|
||||
Color oldfg = g.getColor();
|
||||
Shape oldclip = g.getClip();
|
||||
|
||||
// XXX save font?
|
||||
|
||||
g.clipRect(mx, my, mw, mh);
|
||||
|
||||
if(solids != null) {
|
||||
for(int i=0; i<nsolids; i++) {
|
||||
g.setColor(solids[i]);
|
||||
g.fillRect(mx+(mw*i)/nsolids, my, mw/nsolids+1, mh);
|
||||
}
|
||||
} else {
|
||||
g.setColor(bg);
|
||||
g.fillRect(mx, my, mw, mh);
|
||||
}
|
||||
|
||||
g.setColor(oldfg);
|
||||
|
||||
renderContent(g, mx, my, mw, mh);
|
||||
|
||||
// XXX Span indication???
|
||||
|
||||
if(drawBorder) {
|
||||
g.drawRect(mx, my, mw-1, mh-1);
|
||||
if(mh >= 14) {
|
||||
g.drawRect(mx+1, my+1, mw-3, mh-3);
|
||||
}
|
||||
}
|
||||
g.setClip(oldclip);
|
||||
}
|
||||
|
||||
/** Adds one more solid color to be drawn inside
|
||||
* the cell.
|
||||
*/
|
||||
public boolean addColor(Color c) {
|
||||
if(solids == null || nsolids >= solids.length) {
|
||||
Color[] n= new Color[nsolids + 10];
|
||||
if(solids != null) System.arraycopy(solids, 0, n, 0, nsolids);
|
||||
solids = n;
|
||||
}
|
||||
solids[nsolids++] = c;
|
||||
return false;
|
||||
}
|
||||
/** The currently put solid colors.
|
||||
* null = none. There may be null references near the end
|
||||
* of the array. Mostly useful for checking for nullness.
|
||||
*/
|
||||
public Color[] getSolidColors() { return solids; }
|
||||
|
||||
public CellBgFlob(int x, int y, int d, int w, int h,
|
||||
ZZCell c) {
|
||||
super(x, y, d, w, h, c);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
105
Java/flob/CellFlob1.java
Normal file
105
Java/flob/CellFlob1.java
Normal file
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
CellFlob1.java
|
||||
*
|
||||
* Copyright (c) 1999-2000, Ted Nelson and Tuomas Lukka
|
||||
*
|
||||
* You may use and distribute under the terms of either the GNU Lesser
|
||||
* General Public License, either version 2 of the license or,
|
||||
* at your choice, any later version. Alternatively, you may use and
|
||||
* distribute under the terms of the XPL.
|
||||
*
|
||||
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
|
||||
* the licenses.
|
||||
*
|
||||
* This software 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 README
|
||||
* file for more details.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Written by Tuomas Lukka
|
||||
*/
|
||||
|
||||
package org.gzigzag;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.util.*;
|
||||
|
||||
public class CellFlob1 extends BoxedFlob {
|
||||
public static final String rcsid = "$Id: CellFlob1.java,v 1.16 2001/03/18 17:50:16 bfallenstein Exp $";
|
||||
public static final boolean dbg = true;
|
||||
|
||||
String s;
|
||||
Font f;
|
||||
// XXX Should this *really* need to be stored here?
|
||||
FontMetrics fm;
|
||||
|
||||
/** Font height. */
|
||||
int fh;
|
||||
int fasc;
|
||||
/** String width. */
|
||||
int sw;
|
||||
|
||||
ZZCell strCell;
|
||||
|
||||
int xoffs = 0; // Previously, these margins where three, but at the moment
|
||||
int yoffs = 0; // margins are cared for by the BoxTypes
|
||||
|
||||
static public final Dimension getSize(FontMetrics fm, String str,
|
||||
int xoffs, int yoffs) {
|
||||
int w = fm.stringWidth(str) + xoffs * 2 + 2;
|
||||
int h = fm.getHeight() + 2*yoffs;
|
||||
if(w < h) w = h;
|
||||
return new Dimension( w, h );
|
||||
}
|
||||
|
||||
public int getStrX(int ind) {
|
||||
if(fm == null) throw new Error("No fontmetrics");
|
||||
if(ind > s.length()) {
|
||||
// XXX What to do?
|
||||
return x + xoffs + fm.stringWidth(s);
|
||||
}
|
||||
return x + xoffs + fm.stringWidth(s.substring(0, ind)) ;
|
||||
}
|
||||
|
||||
public void render(Graphics g, int mx, int my, int md, int mw, int mh) {
|
||||
Shape oldClip = g.getClip();
|
||||
g.clipRect(mx, my, mw, mh);
|
||||
int ty = my + (mh-fh)/2 + fasc;
|
||||
g.setFont(f);
|
||||
g.drawString(s, mx+xoffs, ty);
|
||||
g.setClip(oldClip);
|
||||
}
|
||||
|
||||
public CellFlob1(int x, int y, int d, int w, int h,
|
||||
ZZCell c, ZZCell strCell, String s,
|
||||
Font f, FontMetrics fm) {
|
||||
super(x, y, d, w, h, c);
|
||||
|
||||
// Not true, since c can be the flob cell and d the referring
|
||||
// cell.
|
||||
// this.s = c.getText();
|
||||
|
||||
this.s = (s==null? "" : s);
|
||||
this.strCell = strCell;
|
||||
|
||||
this.f = f;
|
||||
this.fm = fm;
|
||||
|
||||
this.fh = fm.getAscent()+fm.getDescent();
|
||||
this.fasc = fm.getAscent()+fm.getLeading();
|
||||
this.sw = fm.stringWidth(this.s);
|
||||
}
|
||||
|
||||
public Object hit(int x0, int y0) {
|
||||
if(!insideRect(x0, y0)) return null;
|
||||
// Search for the right position in the string.
|
||||
// We return a virtual cursor.
|
||||
int ind = ZZUtil.findStringHit(s, x0-x-xoffs, fm);
|
||||
|
||||
return new ZZCursorVirtual(strCell, ind);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
205
Java/flob/CellFlobFactory1.zob
Normal file
205
Java/flob/CellFlobFactory1.zob
Normal file
@@ -0,0 +1,205 @@
|
||||
/*
|
||||
RasterFactory1.zob
|
||||
*
|
||||
* Copyright (c) 2000, Ted Nelson and Tuomas Lukka
|
||||
*
|
||||
* You may use and distribute under the terms of either the GNU Lesser
|
||||
* General Public License, either version 2 of the license or,
|
||||
* at your choice, any later version. Alternatively, you may use and
|
||||
* distribute under the terms of the XPL.
|
||||
*
|
||||
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
|
||||
* the licenses.
|
||||
*
|
||||
* This software 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 README
|
||||
* file for more details.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Written by Tuomas Lukka
|
||||
*/
|
||||
|
||||
package org.gzigzag;
|
||||
import java.util.*;
|
||||
import java.awt.*;
|
||||
|
||||
/** A simple cell factory that gives the cells as one-line strings.
|
||||
* Variable length is possible.
|
||||
*/
|
||||
|
||||
public class CellFlobFactory1 implements FlobFactory, ZOb {
|
||||
public static final String rcsid = "$Id$";
|
||||
public static boolean dbg = false;
|
||||
private static void p(String s) { if(dbg) ZZLogger.log(s); }
|
||||
private static void pa(String s) { ZZLogger.log(s); }
|
||||
|
||||
STRUCTPARAMS {
|
||||
|
||||
/** The string to use to get the default cell width. */
|
||||
String widthstr
|
||||
= "0000000000";
|
||||
|
||||
/** The default background color.
|
||||
* XXX Currently, because of color mixing, the foreground
|
||||
* comes from FlobSet. This should maybe change - check later.
|
||||
*/
|
||||
Color bg
|
||||
= Color.white;
|
||||
|
||||
/** The font for the default enlargement. */
|
||||
ScalableFont font
|
||||
= new ScalableFont("SansSerif", Font.PLAIN, 12);
|
||||
|
||||
/** Whether the font changes size with the enlargement. */
|
||||
boolean zoomfont
|
||||
= true;
|
||||
|
||||
/** Whether the font can get bigger than the default font.
|
||||
* Ignored (or rather, doesn't have any effect) when zoomfont is false.
|
||||
*/
|
||||
boolean enlargefont
|
||||
= true;
|
||||
|
||||
/** The x and y margins
|
||||
*/
|
||||
int[] margins
|
||||
= new int[] {2, 1};
|
||||
|
||||
/** Whether to produce BallCells instead?
|
||||
*/
|
||||
boolean ball
|
||||
= false;
|
||||
}
|
||||
|
||||
/*
|
||||
RasterCellFactory1(Component c) {
|
||||
comp = c;
|
||||
}
|
||||
*/
|
||||
|
||||
protected Font fon(int scale) { return font.getFont(scale); }
|
||||
protected FontMetrics fonmet(int scale) {
|
||||
return font.getFontMetrics(scale);
|
||||
}
|
||||
protected int getScale(float fract) { return getScale(fract,false); }
|
||||
protected int getScale(float fract,boolean real) {
|
||||
if(!enlargefont && !real && fract>=1.0) return 1000;
|
||||
return (int)(fract*1000);
|
||||
}
|
||||
|
||||
public Dimension getSize(ZZCell c, float fract) {
|
||||
String str = widthstr;
|
||||
if(c != null) str = c.getText();
|
||||
if(str == null) str = "";
|
||||
FontMetrics fm = fonmet(getScale(fract,true));
|
||||
if(ball)
|
||||
return BallCell.getSize(fm, str, margins[0], margins[1]);
|
||||
else
|
||||
return CellFlob1.getSize(fm, str, margins[0], margins[1]);
|
||||
}
|
||||
|
||||
public Flob makeFlob(FlobSet into, ZZCell c, ZZCell handleCell,
|
||||
float fract,
|
||||
int x, int y, int d, int w, int h) {
|
||||
int scale = getScale(fract);
|
||||
Font f = fon(scale);
|
||||
FontMetrics fm = fonmet(scale);
|
||||
if(ball) {
|
||||
BallCell cf = new BallCell(x, y, d, w, h, handleCell, c,
|
||||
c.getText(), f, fm, into);
|
||||
cf.xoffs = margins[0];
|
||||
cf.yoffs = margins[1];
|
||||
addSolidColors(into, cf, cf);
|
||||
into.add(cf);
|
||||
return cf;
|
||||
} else {
|
||||
CellFlob1 cf = new CellFlob1(x, y, d, w, h, handleCell, c,
|
||||
c.getText(), f, fm);
|
||||
cf.bg = bg;
|
||||
cf.xoffs = margins[0];
|
||||
cf.yoffs = margins[1];
|
||||
addSolidColors(into, cf, cf);
|
||||
into.add(cf);
|
||||
return cf;
|
||||
}
|
||||
}
|
||||
public Flob placeFlob(FlobSet into, ZZCell c, ZZCell handleCell,
|
||||
float fract,
|
||||
int x, int y, int depth,
|
||||
float xfract, float yfract) {
|
||||
Dimension d = getSize(c, fract);
|
||||
return makeFlob(into, c, handleCell, fract,
|
||||
(int)(x-xfract*d.width),
|
||||
(int)(y-yfract*d.height),
|
||||
depth, d.width, d.height);
|
||||
}
|
||||
|
||||
public Flob centerFlob(FlobSet into, ZZCell c, ZZCell handleCell,
|
||||
float fract, Point p, int xalign, int yalign,
|
||||
int depth, Dimension d) {
|
||||
if(d == null) d = getSize(c, fract);
|
||||
int x, y;
|
||||
if(ball) {
|
||||
x = p.x - d.height/2; y = p.y - d.height/2;
|
||||
} else {
|
||||
x = p.x - d.width/2; y = p.y - d.height/2;
|
||||
}
|
||||
if(xalign < 0) x = p.x;
|
||||
if(xalign > 0) x = p.x - d.width;
|
||||
if(yalign < 0) y = p.y;
|
||||
if(yalign > 0) y = p.y - d.height;
|
||||
p("centerFlob "+p+" "+d+" at "+x+" "+y+" align "+xalign+" "+yalign);
|
||||
return makeFlob(into, c, handleCell, fract, x, y,
|
||||
depth, d.width, d.height);
|
||||
}
|
||||
public Flob centerFlob(FlobSet into, ZZCell c, ZZCell handleCell,
|
||||
float fract, Point p, int xalign, int yalign, int depth) {
|
||||
return centerFlob(into, c, handleCell, fract, p, xalign, yalign,
|
||||
depth, null);
|
||||
}
|
||||
|
||||
/** A routine to add solid background colors according to scheme 1.
|
||||
* No better place to put it right now, but this routine can be
|
||||
* called from anywhere to color the background of a cellbgflob
|
||||
* as requested.
|
||||
* Also adds line cursors, if any.
|
||||
*/
|
||||
static public void addSolidColors(FlobSet into, Flob f, Colorer col) {
|
||||
// Special case check: Is this a cursor or a cursor's clone?
|
||||
ZZCell orig = f.c.h("d.clone", -1);
|
||||
if(orig.h("d.cursor-list", -1).s("d.cursor", -1)
|
||||
!= null) {
|
||||
col.addColor(ZZCursorReal.getColorOrWhite(orig));
|
||||
return; // XXX should draw line cursors!
|
||||
}
|
||||
|
||||
Enumeration e = ZZCursorReal.getPointers(f.c);
|
||||
while(e.hasMoreElements()) {
|
||||
ZZCell cu = (ZZCell)e.nextElement();
|
||||
Color color = ZZCursorReal.getColor(cu);
|
||||
if(color != null) if(col.addColor(color)) return;
|
||||
if(!(f instanceof CellFlob1)) continue;
|
||||
int offs = ZZCursorReal.getOffs(cu);
|
||||
if(offs == ZZCursor.NO_OFFSET) continue;
|
||||
int x = ((CellFlob1)f).getStrX(offs);
|
||||
into.add(new LineDecor(x, f.y, x, f.y+f.h,
|
||||
Color.black, f.d));
|
||||
}
|
||||
|
||||
// XXX Does not check whose mark it is - should!
|
||||
if(f.c.s("d.mark-set", 1)!=null)
|
||||
if(col.addColor(Color.red)) return;
|
||||
|
||||
if(f.c.s("d.clone", -1) != null)
|
||||
if(col.addColor(Color.yellow)) return;
|
||||
else if(f.c.s("d.clone", 1) != null)
|
||||
if(col.addColor(new Color(255, 255, 192))) return;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// vim: set syntax=java :
|
||||
207
Java/flob/CellFlobFactory2.zob
Normal file
207
Java/flob/CellFlobFactory2.zob
Normal file
@@ -0,0 +1,207 @@
|
||||
/*
|
||||
RasterFactory2.zob
|
||||
*
|
||||
* Copyright (c) 2000, Ted Nelson and Tuomas Lukka
|
||||
*
|
||||
* You may use and distribute under the terms of either the GNU Lesser
|
||||
* General Public License, either version 2 of the license or,
|
||||
* at your choice, any later version. Alternatively, you may use and
|
||||
* distribute under the terms of the XPL.
|
||||
*
|
||||
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
|
||||
* the licenses.
|
||||
*
|
||||
* This software 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 README
|
||||
* file for more details.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Written by Tuomas Lukka, multiline by Benjamin Fallenstein
|
||||
*/
|
||||
|
||||
package org.gzigzag;
|
||||
import java.util.*;
|
||||
import java.awt.*;
|
||||
|
||||
/** A simple cell factory that gives the cells as one-line strings.
|
||||
* Variable length is possible.
|
||||
* XXX This class is a bad copy of RasterCellFactory 1.
|
||||
* Inheritance should be rather used, but doesn't work yet with ZObs.
|
||||
*/
|
||||
|
||||
public class CellFlobFactory2 implements FlobFactory, ZOb {
|
||||
public static final String rcsid = "$Id$";
|
||||
public static boolean dbg = false;
|
||||
private static final void p(String s) { if(dbg) System.out.println(s); }
|
||||
private static final void pa(String s) { System.out.println(s); }
|
||||
|
||||
STRUCTPARAMS {
|
||||
|
||||
/** The string to use to get the default cell width. */
|
||||
String widthstr
|
||||
= "0000000000";
|
||||
|
||||
/** The default background color.
|
||||
* XXX Currently, because of color mixing, the foreground
|
||||
* comes from FlobSet. This should maybe change - check later.
|
||||
*/
|
||||
Color bg
|
||||
= Color.white;
|
||||
|
||||
/** The font for the default enlargement. */
|
||||
ScalableFont font
|
||||
= new ScalableFont("SansSerif", Font.PLAIN, 12);
|
||||
|
||||
/** Whether the font changes size with the enlargement. */
|
||||
boolean zoomfont
|
||||
= true;
|
||||
|
||||
/** Whether the font can get bigger than the default font.
|
||||
* Ignored (or rather, doesn't have any effect) when zoomfont is false.
|
||||
*/
|
||||
boolean enlargefont
|
||||
= true;
|
||||
|
||||
/** The x and y margins
|
||||
*/
|
||||
int[] margins
|
||||
= new int[] {3, 2};
|
||||
|
||||
ZOb ftextlayouter
|
||||
= new FTextLayouter();
|
||||
|
||||
}
|
||||
|
||||
protected Font fon(int scale) { return font.getFont(scale); }
|
||||
protected FontMetrics fonmet(int scale) {
|
||||
return font.getFontMetrics(scale);
|
||||
}
|
||||
protected int getScale(float fract) { return getScale(fract, false); }
|
||||
protected int getScale(float fract, boolean real) {
|
||||
if(!enlargefont && !real && fract>=1.0) return 1000;
|
||||
return (int)(fract*1000);
|
||||
}
|
||||
|
||||
public Dimension getSize(ZZCell c, float fract) {
|
||||
String str = widthstr;
|
||||
if(c != null) str = c.getText();
|
||||
if(str == null) str = "";
|
||||
FontMetrics fm = fonmet(getScale(fract, true));
|
||||
return CellFlob1.getSize(fm, str, margins[0]*2, margins[1]*2);
|
||||
}
|
||||
|
||||
public Flob makeFlob(FlobSet into, ZZCell c, ZZCell handleCell,
|
||||
float fract, int x, int y, int d, int w, int h) {
|
||||
int scale = getScale(fract);
|
||||
Font f = fon(scale);
|
||||
FontMetrics fm = fonmet(scale);
|
||||
CellBgFlob cf = new CellBgFlob(x, y, d, w, h, c);
|
||||
Point p = cf.getPoint(1, 1);
|
||||
p = cf.getPoint(-1, -1);
|
||||
cf.bg = bg;
|
||||
int xm = margins[0], ym = margins[1];
|
||||
addSolidColors(into, cf);
|
||||
|
||||
FText ftxt = new FText(new FText.Part[] {
|
||||
new FText.CellPart(c, 0, -1, f, fm, null, null)
|
||||
});
|
||||
Rectangle rect = new Rectangle(x+xm, y+ym, w-xm-xm, h-ym-ym);
|
||||
|
||||
// XXX -- make this work! (shall place cursor in middle if text too long)
|
||||
// int offs = -1;
|
||||
// for(Enumeration e=ZZCursorReal.getPointers(c); e.hasMoreElements();) {
|
||||
// int offs0 = ZZCursorReal.getOffs((ZZCell)e.nextElement());
|
||||
// if(offs0 != ZZCursorReal.NO_OFFSET) { offs = offs0; break; }
|
||||
// }
|
||||
|
||||
FTextLayouter ftl = (FTextLayouter)ftextlayouter;
|
||||
ftl.firstCap = false;
|
||||
// if(offs < 0)
|
||||
ftl.place(into, ftxt, rect, d, 1, rect.y+1, 0, true, cf);
|
||||
// else
|
||||
// ftl.place(into, ftxt, rect, d, 0,
|
||||
// rect.y+rect.height/2-fm.getHeight()/2, offs, true, cf);
|
||||
|
||||
into.add(cf);
|
||||
return cf;
|
||||
}
|
||||
public Flob placeFlob(FlobSet into, ZZCell c, ZZCell handleCell,
|
||||
float fract,
|
||||
int x, int y, int depth,
|
||||
float xfract, float yfract) {
|
||||
Dimension d = getSize(c, fract);
|
||||
return makeFlob(into, c, handleCell, fract,
|
||||
(int)(x-xfract*d.width),
|
||||
(int)(y-yfract*d.height),
|
||||
depth, d.width, d.height);
|
||||
|
||||
}
|
||||
|
||||
public Flob centerFlob(FlobSet into, ZZCell c, ZZCell handleCell,
|
||||
float fract, Point p, int xalign, int yalign,
|
||||
int depth, Dimension d) {
|
||||
if(d == null) d = getSize(c, fract);
|
||||
int x, y;
|
||||
x = p.x - d.width/2; y = p.y - d.height/2;
|
||||
if(xalign < 0) x = p.x - d.width;
|
||||
if(xalign > 0) x = p.x;
|
||||
if(yalign < 0) y = p.y - d.height;
|
||||
if(yalign > 0) y = p.y;
|
||||
return makeFlob(into, c, handleCell, fract, x, y,
|
||||
depth, d.width, d.height);
|
||||
}
|
||||
public Flob centerFlob(FlobSet into, ZZCell c, ZZCell handleCell,
|
||||
float fract, Point p, int xalign, int yalign, int depth) {
|
||||
return centerFlob(into, c, handleCell, fract, p, xalign, yalign,
|
||||
depth, null);
|
||||
}
|
||||
|
||||
/** A routine to add solid background colors according to scheme 1.
|
||||
* No better place to put it right now, but this routine can be
|
||||
* called from anywhere to color the background of a cellbgflob
|
||||
* as requested.
|
||||
* Also adds line cursors, if any.
|
||||
*/
|
||||
static public void addSolidColors(FlobSet into, CellBgFlob f) {
|
||||
// Special case check: Is this a cursor or a cursor's clone?
|
||||
ZZCell orig = f.c.h("d.clone", -1);
|
||||
if(orig.h("d.cursor-list", -1).s("d.cursor", -1)
|
||||
!= null) {
|
||||
f.addColor(ZZCursorReal.getColorOrWhite(orig));
|
||||
return; // XXX should draw line cursors!
|
||||
}
|
||||
|
||||
ZZCell cu = f.c.s("d.cursor", 1);
|
||||
|
||||
while(cu != null) {
|
||||
Color color = ZZCursorReal.getColor(cu);
|
||||
if(color != null) f.addColor(color);
|
||||
// String txt = cu.getText();
|
||||
// if(txt != null && !txt.equals("") && f instanceof CellBgFlob) {
|
||||
// try {
|
||||
// int ind = Integer.parseInt(txt);
|
||||
// int x = ((CellBgFlob)f).getStrX(ind);
|
||||
// into.add(new LineDecor(x, f.y, x, f.y+f.h,
|
||||
// Color.black, f.d));
|
||||
// } catch(NumberFormatException e) {
|
||||
// }
|
||||
// }
|
||||
cu = cu.s("d.cursor-list", 1);
|
||||
}
|
||||
// XXX Does not check whose mark it is - should!
|
||||
if(f.c.s("d.mark-set", 1)!=null)
|
||||
f.addColor(Color.red);
|
||||
|
||||
if(f.c.s("d.clone", -1) != null)
|
||||
f.addColor(Color.yellow);
|
||||
else if(f.c.s("d.clone", 1) != null)
|
||||
f.addColor(new Color(255, 255, 192));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// vim: set syntax=java :
|
||||
41
Java/flob/Colorer.java
Normal file
41
Java/flob/Colorer.java
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
Colorer.java
|
||||
*
|
||||
* Copyright (c) 2000, Ted Nelson and Tuomas Lukka
|
||||
*
|
||||
* You may use and distribute under the terms of either the GNU Lesser
|
||||
* General Public License, either version 2 of the license or,
|
||||
* at your choice, any later version. Alternatively, you may use and
|
||||
* distribute under the terms of the XPL.
|
||||
*
|
||||
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
|
||||
* the licenses.
|
||||
*
|
||||
* This software 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 README
|
||||
* file for more details.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Written by Tuomas Lukka
|
||||
*/
|
||||
package org.gzigzag;
|
||||
import java.awt.*;
|
||||
|
||||
/** An interface for coloring cell background -like things.
|
||||
* The information about how many colors are appropriate should
|
||||
* move separately from this.
|
||||
*/
|
||||
|
||||
public interface Colorer {
|
||||
String rcsid = "$Id: Colorer.java,v 1.1 2000/10/26 18:15:05 tjl Exp $";
|
||||
/** Add the given color to the set of colors to be shown in the background,
|
||||
* or whatever.
|
||||
* It is assumed that the colors come more significant first, so that
|
||||
* Colorers are free to take any number of the first ones and ignore
|
||||
* the rest.
|
||||
* @return Whether the rest of the colors will be ignored.
|
||||
*/
|
||||
boolean addColor(Color c);
|
||||
}
|
||||
58
Java/flob/CombinedView.zob
Normal file
58
Java/flob/CombinedView.zob
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
CombinedView.zob
|
||||
*
|
||||
* You may use and distribute under the terms of either the GNU Lesser
|
||||
* General Public License, either version 2 of the license or,
|
||||
* at your choice, any later version. Alternatively, you may use and
|
||||
* distribute under the terms of the XPL.
|
||||
*
|
||||
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
|
||||
* the licenses.
|
||||
*
|
||||
* This software 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 README
|
||||
* file for more details.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Written by Benjamin Fallenstein
|
||||
*/
|
||||
|
||||
package org.gzigzag;
|
||||
import java.awt.*;
|
||||
|
||||
/** A view that shows all views of the accursed cell next to each other.
|
||||
*/
|
||||
|
||||
public class CombinedView implements FlobView, ZOb {
|
||||
public static final String rcsid = "$Id: CombinedView.zob,v 1.6 2000/12/31 15:15:50 bfallenstein Exp $";
|
||||
/** Should we print out debugging info? */
|
||||
public static boolean dbg = false;
|
||||
static final void p(String s) { if(dbg) pa(s); }
|
||||
static final void pa(String s) { System.out.println(s); }
|
||||
|
||||
STRUCTPARAMS {}
|
||||
|
||||
public void raster(FlobSet into, FlobFactory fact,
|
||||
ZZCell win, String[] dims, ZZCell accursed) {
|
||||
ZZCell[] apps = ApplitudeMgr.getApplitudes(accursed);
|
||||
if(apps.length == 0)
|
||||
apps = new ZZCell[] { ApplitudeMgr.getFallback(win.getSpace()) };
|
||||
int n = apps.length;
|
||||
|
||||
ZZCell pref = ApplitudeMgr.getWindowApp(win);
|
||||
Dimension size = new Dimension(into.getSize());
|
||||
if(pref != null)
|
||||
fact.centerFlob(into, pref, pref, (float)1.5,
|
||||
new Point(size.width, size.height), 1, 1, 1);
|
||||
size.width = size.width / n;
|
||||
|
||||
for(int i=0; i<n; i++) {
|
||||
FlobSet set = into.create(size);
|
||||
FlobView view = ApplitudeMgr.getView(apps[i]);
|
||||
view.raster(set, fact, win, dims, accursed);
|
||||
into.fetch(set, size.width * i, 0, 0, apps[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
149
Java/flob/CompassView.zob
Normal file
149
Java/flob/CompassView.zob
Normal file
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
CompassRaster.zob
|
||||
*
|
||||
* You may use and distribute under the terms of either the GNU Lesser
|
||||
* General Public License, either version 2 of the license or,
|
||||
* at your choice, any later version. Alternatively, you may use and
|
||||
* distribute under the terms of the XPL.
|
||||
*
|
||||
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
|
||||
* the licenses.
|
||||
*
|
||||
* This software 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 README
|
||||
* file for more details.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Written by Tuukka Hastrup
|
||||
*/
|
||||
|
||||
|
||||
package org.gzigzag;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.lang.Math;
|
||||
import java.awt.Color;
|
||||
import java.awt.Font;
|
||||
import java.awt.FontMetrics;
|
||||
import java.util.Vector;
|
||||
|
||||
|
||||
public class CompassView implements FlobView, ZOb {
|
||||
public static final String rcsid = "$Id$";
|
||||
public static boolean dbg = true;
|
||||
static final void p(String s) { if(dbg) System.out.println(s); }
|
||||
static final void pa(String s) { System.out.println(s); }
|
||||
|
||||
STRUCTPARAMS {
|
||||
Font dfont = new Font("SansSerif", Font.PLAIN, 12);
|
||||
}
|
||||
|
||||
int dfonth;
|
||||
FontMetrics dfm;
|
||||
|
||||
INITIALIZE {
|
||||
dfm = FONTMETRICS(dfont);
|
||||
dfonth = dfm.getHeight();
|
||||
}
|
||||
|
||||
|
||||
public void raster(FlobSet into, FlobFactory fact, ZZCell view,
|
||||
String[]vds, ZZCell accursed) {
|
||||
|
||||
Dimension d = into.getSize();
|
||||
int midx = d.width / 2;
|
||||
int midy = d.height / 2;
|
||||
Dimension c = fact.getSize(null, 1);
|
||||
int cw = c.width;
|
||||
int ch = c.height;
|
||||
|
||||
ZZCell stdim = ZZCursorReal.get(view.s("d.dims", 1));
|
||||
|
||||
/* ZZConnection[] conns = accursed.getConns();
|
||||
for (int i = 0; i < conns.length; i++)
|
||||
System.out.println("Conn #" + i + ": " +
|
||||
conns[i].c1.getID() + "-<" +
|
||||
conns[i].c2.getID() + (conns[i].dir == -1 ?
|
||||
"-" : "") +
|
||||
conns[i].dim + ">-" +
|
||||
conns[i].c2.getID());*/
|
||||
|
||||
Vector dims = new Vector(); // Dims to be drawn
|
||||
Vector pos = new Vector(); // Cells to positive directions to be drawn
|
||||
Vector neg = new Vector(); // Cells to negative directions to be drawn
|
||||
|
||||
ZZCell dim, pc, nc;
|
||||
dim=stdim;
|
||||
do { // Go through the DimList starting from the x-axis dimension
|
||||
String cdim = dim.getText();
|
||||
p("Found dim: "+cdim);
|
||||
pc = accursed.s(cdim, 1);
|
||||
nc = accursed.s(cdim, -1);
|
||||
if(nc != null || pc != null) {
|
||||
dims.addElement(cdim);
|
||||
pos.addElement(pc);
|
||||
neg.addElement(nc);
|
||||
}
|
||||
dim = dim.s("d.2", 1);
|
||||
} while(dim != stdim); // Do until loop closes
|
||||
|
||||
int numdirs = pos.size()+neg.size(); // Number of cells and thus sectors
|
||||
if(numdirs == 0)
|
||||
return; // No cells to draw
|
||||
double angle = 2 * Math.PI / (numdirs);
|
||||
int l = (int) ((d.height < d.width ? d.height : d.width) / 2 * 0.5);
|
||||
|
||||
fact.makeFlob(into, accursed, accursed, 1,
|
||||
(d.width-cw) / 2, (d.height-ch) / 2, 1, cw, ch);
|
||||
|
||||
int i = 0;
|
||||
LineDecor.Builder nldb = new LineDecor.Builder(into, Color.black);
|
||||
LineDecor.Builder pldb = new LineDecor.Builder(into, Color.red);
|
||||
nldb.startl(numdirs/2*4, 12);
|
||||
pldb.startl(numdirs/2*4, 12);
|
||||
|
||||
double a = (double)-2/3*Math.PI; // Begin placing positive cells top left
|
||||
while (i < numdirs/2) {
|
||||
int dx = x(a, l);
|
||||
int dy = y(a, l);
|
||||
|
||||
if(pos.elementAt(i)!=null) {
|
||||
fact.makeFlob(into, (ZZCell)pos.elementAt(i), (ZZCell)pos.elementAt(i),
|
||||
(float) 0.7,
|
||||
midx + dx-cw/2, midy + dy-ch/2,
|
||||
1, cw, ch);
|
||||
pldb.l(midx, midy, midx + dx, midy + dy);
|
||||
into.add(new TextDecor(
|
||||
midx+dx+cw/2-dfm.stringWidth("+"+(String)dims.elementAt(i)),
|
||||
midy+dy-ch/2, "+"+(String)dims.elementAt(i), Color.red, dfont));
|
||||
}
|
||||
if(neg.elementAt(i)!=null) {
|
||||
fact.makeFlob(into, (ZZCell)neg.elementAt(i), (ZZCell)neg.elementAt(i),
|
||||
(float) 0.7,
|
||||
midx -dx -cw/2, midy -dy -ch/2,
|
||||
1, cw, ch);
|
||||
nldb.l(midx, midy, midx -dx, midy -dy);
|
||||
into.add(new TextDecor(
|
||||
midx-dx-cw/2, midy-dy+ch/2+dfonth,
|
||||
"-"+(String)dims.elementAt(i), Color.black, dfont));
|
||||
}
|
||||
|
||||
i++;
|
||||
a += angle; // Rotate clockwise
|
||||
}
|
||||
nldb.endl();
|
||||
pldb.endl();
|
||||
}
|
||||
|
||||
protected int x(double angle, int length) {
|
||||
return (int) (Math.cos(angle) * length);
|
||||
}
|
||||
|
||||
protected int y(double angle, int length) {
|
||||
return (int) (Math.sin(angle) * length);
|
||||
}
|
||||
}
|
||||
|
||||
// vim: set syntax=java :
|
||||
174
Java/flob/ConnectionLineDecor.java
Normal file
174
Java/flob/ConnectionLineDecor.java
Normal file
@@ -0,0 +1,174 @@
|
||||
/*
|
||||
ConnectionLineDecor.java
|
||||
*
|
||||
* Copyright (c) 2000, Ted Nelson and Tuomas Lukka
|
||||
*
|
||||
* You may use and distribute under the terms of either the GNU Lesser
|
||||
* General Public License, either version 2 of the license or,
|
||||
* at your choice, any later version. Alternatively, you may use and
|
||||
* distribute under the terms of the XPL.
|
||||
*
|
||||
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
|
||||
* the licenses.
|
||||
*
|
||||
* This software 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 README
|
||||
* file for more details.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Written by Tuomas Lukka
|
||||
*/
|
||||
|
||||
package org.gzigzag;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.util.*;
|
||||
|
||||
/** A decoration of lines connecting flobs to each other.
|
||||
* Interpolation is done by this class. The coordinates are
|
||||
* given as points inside the flob's rectangle.
|
||||
*/
|
||||
|
||||
public class ConnectionLineDecor extends Flob {
|
||||
public static final String rcsid = "$Id: ConnectionLineDecor.java,v 1.5 2000/09/19 10:31:59 ajk Exp $";
|
||||
public static final boolean dbg = true;
|
||||
static final void p(String s) { if(dbg) System.out.println(s); }
|
||||
static final void pa(String s) { System.out.println(s); }
|
||||
|
||||
/** A class that incrementally builds these.
|
||||
*/
|
||||
static public class Builder {
|
||||
FlobSet into;
|
||||
int curp; int np;
|
||||
Flob[] flobs;
|
||||
int[] p;
|
||||
Color col;
|
||||
int d;
|
||||
public Builder(FlobSet into, Color col) {
|
||||
this.into = into;
|
||||
this.col = col;
|
||||
}
|
||||
public final void startl(int n, int d) {
|
||||
if(curp != 0) endl();
|
||||
this.d = d;
|
||||
curp = 0;
|
||||
np = n;
|
||||
p = null;
|
||||
flobs = null;
|
||||
}
|
||||
public final void l(Flob f0, int x0, int y0, Flob f1, int x1, int y1) {
|
||||
if(p==null) {
|
||||
p = new int[np * 4];
|
||||
flobs = new Flob[np * 2];
|
||||
} else if(curp >= np) {
|
||||
endl();
|
||||
p = new int[np * 4];
|
||||
flobs = new Flob[np * 2];
|
||||
curp = 0;
|
||||
}
|
||||
flobs[curp*2 + 0] = f0;
|
||||
flobs[curp*2 + 1] = f1;
|
||||
p[curp*4 + 0] = x0;
|
||||
p[curp*4 + 1] = y0;
|
||||
p[curp*4 + 2] = x1;
|
||||
p[curp*4 + 3] = y1;
|
||||
curp ++;
|
||||
}
|
||||
public void endl() {
|
||||
if(p==null) return;
|
||||
into.add(new ConnectionLineDecor(flobs, p, curp, col, d));
|
||||
p = null; flobs = null; curp = 0;
|
||||
}
|
||||
}
|
||||
|
||||
Color color;
|
||||
int n;
|
||||
Flob[] flobs;
|
||||
int[] coords; // 256th parts
|
||||
|
||||
public ConnectionLineDecor(Flob[] flobs, int[] coords, int n, int d) {
|
||||
this(flobs, coords, n, null, d);
|
||||
}
|
||||
|
||||
/** Usual constructor.
|
||||
* @param coords The coordinates for the lines, given as
|
||||
* quadruplets x1, y1, x2, y2.
|
||||
*/
|
||||
public ConnectionLineDecor(Flob[] flobs, int[] coords, int n, Color color, int d) {
|
||||
// XXX Is size 0x0 right?
|
||||
super(0, 0, d, 0, 0, null);
|
||||
this.flobs = flobs;
|
||||
this.coords = coords;
|
||||
this.n = n;
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
public void render(Graphics g) {
|
||||
Color old = null;
|
||||
if(color != null) {
|
||||
old = g.getColor();
|
||||
g.setColor(color);
|
||||
}
|
||||
g.setColor(Color.black);
|
||||
p("Drawing flobconns");
|
||||
|
||||
for(int i=0; i<n; i++) {
|
||||
Flob f1 = flobs[i*2];
|
||||
Flob f2 = flobs[i*2+1];
|
||||
p("Draw: "+
|
||||
f1.x+" "+f1.y+" "+f1.w+" "+f1.h+" "+
|
||||
f2.x+" "+f2.y+" "+f2.w+" "+f2.h+" "+
|
||||
coords[i*4]+" "+
|
||||
coords[i*4+1]+" "+
|
||||
coords[i*4+2]+" "+
|
||||
coords[i*4+3]+" ");
|
||||
g.drawLine(
|
||||
f1.x + (f1.w * coords[i*4])/256,
|
||||
f1.y + (f1.h * coords[i*4+1])/256,
|
||||
f2.x + (f2.w * coords[i*4+2])/256,
|
||||
f2.y + (f2.h * coords[i*4+3])/256
|
||||
);
|
||||
}
|
||||
|
||||
if(old != null)
|
||||
g.setColor(old);
|
||||
}
|
||||
|
||||
public void renderInterp(Graphics g, float fract) {
|
||||
Color old = null;
|
||||
if(color != null) {
|
||||
old = g.getColor();
|
||||
g.setColor(color);
|
||||
}
|
||||
g.setColor(Color.black);
|
||||
|
||||
for(int i=0; i<n; i++) {
|
||||
Flob f1 = flobs[i*2];
|
||||
Flob f1i = f1.interpTo;
|
||||
Flob f2 = flobs[i*2+1];
|
||||
Flob f2i = f2.interpTo;
|
||||
int c1x = f1.x + (f1.w * coords[i*4])/256;
|
||||
int c1y = f1.y + (f1.h * coords[i*4+1])/256;
|
||||
int c2x = f2.x + (f2.w * coords[i*4+2])/256;
|
||||
int c2y = f2.y + (f2.h * coords[i*4+3])/256;
|
||||
int ic1x = f1i.x + (f1i.w * coords[i*4])/256;
|
||||
int ic1y = f1i.y + (f1i.h * coords[i*4+1])/256;
|
||||
int ic2x = f2i.x + (f2i.w * coords[i*4+2])/256;
|
||||
int ic2y = f2i.y + (f2i.h * coords[i*4+3])/256;
|
||||
|
||||
g.drawLine(
|
||||
(int)(c1x + fract * (ic1x - c1x)),
|
||||
(int)(c1y + fract * (ic1y - c1y)),
|
||||
(int)(c2x + fract * (ic2x - c2x)),
|
||||
(int)(c2y + fract * (ic2y - c2y))
|
||||
);
|
||||
}
|
||||
|
||||
if(old != null)
|
||||
g.setColor(old);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
122
Java/flob/CoordDecor.java
Normal file
122
Java/flob/CoordDecor.java
Normal file
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
CoordDecor.java
|
||||
*
|
||||
* Copyright (c) 2000, Ted Nelson and Tuomas Lukka
|
||||
*
|
||||
* You may use and distribute under the terms of either the GNU Lesser
|
||||
* General Public License, either version 2 of the license or,
|
||||
* at your choice, any later version. Alternatively, you may use and
|
||||
* distribute under the terms of the XPL.
|
||||
*
|
||||
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
|
||||
* the licenses.
|
||||
*
|
||||
* This software 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 README
|
||||
* file for more details.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Written by Tuomas Lukka
|
||||
*/
|
||||
|
||||
package org.gzigzag;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.util.*;
|
||||
|
||||
/** A base class from which to derive fast decorations with coordinates.
|
||||
*/
|
||||
|
||||
abstract public class CoordDecor extends Renderable {
|
||||
public static final String rcsid = "$Id: CoordDecor.java,v 1.7 2000/12/26 20:15:14 bfallenstein Exp $";
|
||||
public static boolean dbg = false;
|
||||
static void p(String s) { if(dbg) System.out.println(s); }
|
||||
static void pa(String s) { System.out.println(s); }
|
||||
|
||||
/** The number of coordinates.
|
||||
*/
|
||||
int n;
|
||||
/** The coordinates.
|
||||
* Note: the translate() method assumes that at each even index there's
|
||||
* an x coordinate, and at each odd index there's an y coordinate. If
|
||||
* that's not true, override translate() in subclasses (possibly returning
|
||||
* false, if the coords can't be translated).
|
||||
*/
|
||||
int[] coords;
|
||||
|
||||
/** A simple class that knows how to efficiently build
|
||||
* these things. The efficiency comes from always allocating
|
||||
* an array and never letting go of it; adding the arrays to the
|
||||
* flob when they're full and starting fresh.
|
||||
*/
|
||||
static abstract public class Builder {
|
||||
/** The flobset the finished products go into. */
|
||||
FlobSet into;
|
||||
/** The depth of the finished product. */
|
||||
int d;
|
||||
|
||||
/** The nth object being rendered. */
|
||||
int nth;
|
||||
/** The current point index. */
|
||||
int curp;
|
||||
/** The number of point coordinates to reserve. */
|
||||
int np;
|
||||
/** The coordinates. */
|
||||
int[] p;
|
||||
|
||||
public Builder(FlobSet into) {
|
||||
this.into = into;
|
||||
}
|
||||
/** Start a set.
|
||||
* @param n The estimated number of coordinates to come.
|
||||
* @param d The depth of the set now begun.
|
||||
*/
|
||||
public void startl(int n, int d) {
|
||||
if(curp != 0) endl();
|
||||
this.d = d;
|
||||
curp = 0;
|
||||
np = n;
|
||||
p = null;
|
||||
}
|
||||
/** Make room for n coordinates. */
|
||||
protected void makeRoom(int l) {
|
||||
if(p!=null && curp + l > p.length)
|
||||
endl();
|
||||
if(p==null)
|
||||
alloc();
|
||||
}
|
||||
/** Allocate the arrays. */
|
||||
protected void alloc() {
|
||||
p = new int[np];
|
||||
curp = 0;
|
||||
nth = 0;
|
||||
}
|
||||
public void endl() {
|
||||
if(p==null) return;
|
||||
into.add(create());
|
||||
p = null; curp = 0;
|
||||
}
|
||||
abstract protected Renderable create();
|
||||
|
||||
}
|
||||
|
||||
public CoordDecor(int[] coords, int n, int d) {
|
||||
this.coords = coords;
|
||||
this.n = n;
|
||||
this.d = d;
|
||||
if(coords != null && coords.length < n)
|
||||
throw new Error("CoordDecor: less length than n!!!");
|
||||
}
|
||||
|
||||
abstract public void render(Graphics g);
|
||||
|
||||
public boolean translate(int x, int y) {
|
||||
for(int i=0; i<coords.length; i+=2) {
|
||||
coords[i] += x;
|
||||
if(i+1 < coords.length) coords[i+1] += y;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
218
Java/flob/CursorView.zob
Normal file
218
Java/flob/CursorView.zob
Normal file
@@ -0,0 +1,218 @@
|
||||
/*
|
||||
CursorView.zob
|
||||
*
|
||||
* You may use and distribute under the terms of either the GNU Lesser
|
||||
* General Public License, either version 2 of the license or,
|
||||
* at your choice, any later version. Alternatively, you may use and
|
||||
* distribute under the terms of the XPL.
|
||||
*
|
||||
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
|
||||
* the licenses.
|
||||
*
|
||||
* This software 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 README
|
||||
* file for more details.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Written by Antti-Juhani Kaijanaho
|
||||
*/
|
||||
|
||||
|
||||
package org.gzigzag;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.*;
|
||||
|
||||
class CursorView implements FlobView, ZOb {
|
||||
public static boolean dbg = false;
|
||||
static final void p(String s) { if(dbg) ZZLogger.log(s); }
|
||||
static final void pa(String s) { ZZLogger.log(s); }
|
||||
|
||||
STRUCTPARAMS {
|
||||
float horizonlevel
|
||||
= (float) 0.5;
|
||||
|
||||
float pointerradius
|
||||
= (float) 0.3;
|
||||
|
||||
float sizefactor
|
||||
= (float) 0.8;
|
||||
|
||||
int initdepth
|
||||
= 2;
|
||||
|
||||
int maxdepth
|
||||
= 8;
|
||||
|
||||
Color linecolor
|
||||
= Color.blue;
|
||||
|
||||
double arrowhead_angle
|
||||
= Math.PI / 6;
|
||||
|
||||
int arrowhead_length
|
||||
= 5;
|
||||
}
|
||||
|
||||
// translation (rotation && scaling) matrices
|
||||
double a00, a01, a10, a11, b00, b01, b10, b11;
|
||||
|
||||
INITIALIZE {
|
||||
if (!(0 < horizonlevel && horizonlevel < 1)) {
|
||||
throw new ZZError("horizonlevel parameter outside ]0,1[");
|
||||
}
|
||||
if (!(0 < pointerradius && pointerradius < 1)) {
|
||||
throw new ZZError("pointerradius parameter outside ]0,1[");
|
||||
}
|
||||
|
||||
a00 = arrowhead_length * Math.cos(arrowhead_angle);
|
||||
a01 = arrowhead_length * Math.sin(arrowhead_angle);
|
||||
a10 = arrowhead_length * -Math.sin(arrowhead_angle);
|
||||
a11 = arrowhead_length * Math.cos(arrowhead_angle);
|
||||
|
||||
b00 = arrowhead_length * Math.cos(arrowhead_angle);
|
||||
b01 = arrowhead_length * -Math.sin(arrowhead_angle);
|
||||
b10 = arrowhead_length * Math.sin(arrowhead_angle);
|
||||
b11 = arrowhead_length * Math.cos(arrowhead_angle);
|
||||
|
||||
}
|
||||
|
||||
Hashtable drawn;
|
||||
|
||||
private void drawPointerCells(FlobSet into, FlobFactory fact,
|
||||
ZZCell centercell, Point centerpoint,
|
||||
int radius, int level, float sfactor) {
|
||||
if (level > maxdepth) return;
|
||||
|
||||
if (drawn.containsKey(centercell)) return;
|
||||
|
||||
Vector pointers = new Vector();
|
||||
|
||||
{
|
||||
Dimension s = fact.getSize(null, 1);
|
||||
int width = (int) (s.width * sfactor);
|
||||
int height = (int) (s.height * sfactor);
|
||||
int x = centerpoint.x - width / 2;
|
||||
int y = centerpoint.y - height / 2;
|
||||
p("radius = " + radius + ", x = " + x + ", y = "
|
||||
+ y + ", width = " + width + ", height = "
|
||||
+ height + ", centercell = " + centercell);
|
||||
Flob fl = fact.makeFlob(into, centercell, centercell, 1,
|
||||
x, y, level, width, height);
|
||||
drawn.put(centercell, centercell);
|
||||
}
|
||||
|
||||
for (Enumeration e = ZZCursorReal.getPointers(centercell);
|
||||
e.hasMoreElements();) {
|
||||
ZZCell c = (ZZCell) e.nextElement();
|
||||
pointers.addElement(c);
|
||||
p("Found cursor " + c);
|
||||
}
|
||||
|
||||
int n = pointers.size();
|
||||
p("n = " + n);
|
||||
|
||||
if (n == 0) return;
|
||||
|
||||
int prad = (int) (pointerradius * radius);
|
||||
|
||||
double baseangle = Math.PI / (n + 1);
|
||||
|
||||
int newradius;
|
||||
{
|
||||
double a = prad - prad * Math.cos(baseangle);
|
||||
double b = prad * Math.sin(baseangle);
|
||||
newradius = (int) Math.sqrt(a * a + b * b);
|
||||
p("a = " + a + ", b = " + b + ", newradius = " + newradius);
|
||||
}
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
ZZCell c = (ZZCell) pointers.elementAt(i);
|
||||
if (ZZCursorReal.get(c) != centercell) pa("WRONG CURSOR CELL FOUND!!!");
|
||||
double angle = (i + 1) * baseangle;
|
||||
p("angle = " + angle + " rad, " + angle * 180 / Math.PI + " deg");
|
||||
int x = (int)(centerpoint.x + prad * Math.cos(angle));
|
||||
int y = (int)(centerpoint.y + prad * Math.sin(angle));
|
||||
drawPointerCells(into, fact, c, new Point(x, y), newradius,
|
||||
level + 1, sfactor * sizefactor);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void raster(final FlobSet into, FlobFactory fact,
|
||||
ZZCell view, String[] dims, ZZCell accursed) {
|
||||
ZZCell c = accursed;
|
||||
Point pt = new Point(into.getSize().width / 2,
|
||||
into.getSize().width / 2);
|
||||
ZZCell ccand = ZZCursorReal.get(c);
|
||||
if (ccand != null) {
|
||||
c = ccand;
|
||||
pt.y /= 2;
|
||||
}
|
||||
drawn = new Hashtable();
|
||||
drawPointerCells(into, fact, c, pt,
|
||||
into.getSize().width, initdepth, 1);
|
||||
|
||||
// Draw the cursor arrows
|
||||
into.iterDepth(new FlobSet.DepthIter() {
|
||||
public void act(Flob[] flobs, int start, int n) {
|
||||
for(int i = start; i < start+n; i++) {
|
||||
ZZCell pointer = flobs[i].c;
|
||||
if (pointer == null) continue;
|
||||
ZZCell pointee = ZZCursorReal.get(pointer);
|
||||
if (pointee == null) continue;
|
||||
p("pointer = " + pointer + ", pointee = " + pointee);
|
||||
Flob from = flobs[i];
|
||||
Flob[] tos = into.findFlobs(null, pointee);
|
||||
for (int j = 0; j < tos.length; j++) {
|
||||
Flob to = (Flob) tos[j];
|
||||
int[] cs = new int[16];
|
||||
// we make the arrow body in two parts:
|
||||
// one from head to arrow point and one
|
||||
// from arrow point to tail
|
||||
cs[0] = from.x + from.w / 2;
|
||||
cs[1] = from.y;
|
||||
cs[2] = to.x + to.w / 2;
|
||||
cs[3] = to.y + to.h;
|
||||
double or1 = (cs[0] + cs[2]) / 2;
|
||||
double or2 = (cs[1] + cs[3]) / 2;
|
||||
cs[6] = cs[2];
|
||||
cs[7] = cs[3];
|
||||
cs[2] = (int) (or1 + 0.5);
|
||||
cs[3] = (int) (or2 + 0.5);
|
||||
cs[4] = cs[2];
|
||||
cs[5] = cs[3];
|
||||
double v1 = cs[0] - cs[2];
|
||||
double v2 = cs[1] - cs[3];
|
||||
double vlen = Math.sqrt(v1*v1 + v2*v2);
|
||||
v1 = v1 / vlen;
|
||||
v2 = v2 / vlen;
|
||||
cs[8] = (int) (or1 + 0.5);
|
||||
cs[9] = (int) (or2 + 0.5);
|
||||
cs[10] = (int) (v1 * a00 + v2 * a01 + or1 + 0.5);
|
||||
cs[11] = (int) (v1 * a10 + v2 * a11 + or2 + 0.5);
|
||||
cs[12] = (int) (or1 + 0.5);
|
||||
cs[13] = (int) (or2 + 0.5);
|
||||
cs[14] = (int) (v1 * b00 + v2 * b01 + or1 + 0.5);
|
||||
cs[15] = (int) (v1 * b10 + v2 * b11 + or2 + 0.5);
|
||||
into.add(new LineDecor(cs, cs.length,
|
||||
linecolor,
|
||||
(from.d + to.d) / 2));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}, true);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
179
Java/flob/FTextCellView.zob
Normal file
179
Java/flob/FTextCellView.zob
Normal file
@@ -0,0 +1,179 @@
|
||||
/*
|
||||
FTextCellView.zob
|
||||
*
|
||||
* Copyright (c) 2001, Benja Fallenstein
|
||||
* Copyright (c) 2000-2001, Ted Nelson and Tuomas Lukka
|
||||
*
|
||||
* You may use and distribute under the terms of either the GNU Lesser
|
||||
* General Public License, either version 2 of the license or,
|
||||
* at your choice, any later version. Alternatively, you may use and
|
||||
* distribute under the terms of the XPL.
|
||||
*
|
||||
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
|
||||
* the licenses.
|
||||
*
|
||||
* This software 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 README
|
||||
* file for more details.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Written by Benja Fallenstein
|
||||
*/
|
||||
|
||||
package org.gzigzag;
|
||||
import java.util.*;
|
||||
import java.awt.*;
|
||||
|
||||
/** A cell view showing some FText.
|
||||
* This class exists in order to make it easy to create cell views which
|
||||
* just take an FText for a cell somehow and then render it on the screen.
|
||||
* Subclasses have to implement getFText(ZZCell, int). Default: render the
|
||||
* cell's content in the specified string.
|
||||
* <p>
|
||||
* XXX Don't use scene flobs. Instead, just place the split cell flobs in the
|
||||
* higher level flob set and create a BoxedFlob 'round them.
|
||||
*/
|
||||
|
||||
public class FTextCellView implements FlobFactory, ZOb {
|
||||
public static final String rcsid = "$Id: FTextCellView.zob,v 1.4 2001/04/02 20:20:54 bfallenstein Exp $";
|
||||
public static boolean dbg = false;
|
||||
private static void p(String s) { if(dbg) ZZLogger.log(s); }
|
||||
private static void pa(String s) { ZZLogger.log(s); }
|
||||
|
||||
// WHAT SUBCLASSES NEED TO OVERRIDE
|
||||
|
||||
/** Get the FText for this cell at the given scale.
|
||||
* scale == fract * 1000.
|
||||
*/
|
||||
protected FText getFText(ZZCell c, int scale) {
|
||||
return new FText(new FText.Part[] {
|
||||
new FText.CellPart(c, 0, -1, f(scale), fm(scale), null, null)
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
// IMPLEMENTATION
|
||||
|
||||
/** Get the font for a given scale. */
|
||||
protected final Font f(int sc) { return font.getFont(sc); }
|
||||
|
||||
/** Get the font metrics for a given scale. */
|
||||
protected final FontMetrics fm(int sc) { return font.getFontMetrics(sc); }
|
||||
|
||||
STRUCTPARAMS {
|
||||
/** The string to use to get the default cell width. */
|
||||
String widthstr
|
||||
= "0000000000";
|
||||
|
||||
/** The default background color.
|
||||
* XXX Currently, because of color mixing, the foreground
|
||||
* comes from FlobSet. This should maybe change - check later.
|
||||
*/
|
||||
Color bg
|
||||
= Color.white;
|
||||
|
||||
/** The font for the default enlargement. */
|
||||
ScalableFont font
|
||||
= new ScalableFont("SansSerif", Font.PLAIN, 12);
|
||||
|
||||
ZOb ftextlayouter
|
||||
= new FTextLayouter(false);
|
||||
|
||||
/** The x and y margins
|
||||
*/
|
||||
int[] margins
|
||||
= new int[] {2, 1};
|
||||
}
|
||||
|
||||
protected int getScale(float fract) {
|
||||
return (int)(fract*1000);
|
||||
}
|
||||
|
||||
public Dimension getSize(ZZCell c, float fract) {
|
||||
if(c != null) {
|
||||
FText ftxt = getFText(c.getRootclone(), getScale(fract));
|
||||
return new Dimension(FText.Part.width(ftxt.parts) + margins[0]*2,
|
||||
FText.Part.height(ftxt.parts) + margins[1]*2);
|
||||
} else {
|
||||
String str = widthstr;
|
||||
if(str == null) str = "";
|
||||
FontMetrics fm = fm(getScale(fract));
|
||||
return CellFlob1.getSize(fm, str, margins[0], margins[1]);
|
||||
}
|
||||
}
|
||||
|
||||
public Flob getFlob(FlobSet into, ZZCell c, FText ftxt,
|
||||
int x, int y, int d, int w, int h) {
|
||||
int xm = margins[0], ym = margins[1];
|
||||
|
||||
BoxedFlob box = new BoxedFlob(x, y, d, w, h, c);
|
||||
|
||||
CellFlobFactory1.addSolidColors(into, box, box);
|
||||
|
||||
Rectangle rect = new Rectangle(x+xm, y+ym, w-xm, h-ym);
|
||||
((FTextLayouter)ftextlayouter).place(into, ftxt, rect, d, 1, y+ym, 0,
|
||||
true, box);
|
||||
|
||||
// Add the box last, so that it is shown under the text.
|
||||
into.add(box);
|
||||
return box;
|
||||
}
|
||||
|
||||
public Flob makeFlob(FlobSet into, ZZCell c, ZZCell handleCell,
|
||||
float fract, int x, int y, int d, int w, int h) {
|
||||
FText ftxt = getFText(c.getRootclone(), getScale(fract));
|
||||
return getFlob(into, c, ftxt, x, y, d, w, h);
|
||||
}
|
||||
|
||||
public Flob placeFlob(FlobSet into, ZZCell c, ZZCell handleCell,
|
||||
float fract,
|
||||
int x, int y, int depth,
|
||||
float xfract, float yfract) {
|
||||
FText ftxt = getFText(c.getRootclone(), getScale(fract));
|
||||
int w = FText.Part.width(ftxt.parts) + margins[0]*2;
|
||||
int h = FText.Part.height(ftxt.parts) + margins[1]*2;
|
||||
return getFlob(into, c, ftxt,
|
||||
(int)(x-xfract*w),
|
||||
(int)(y-yfract*h),
|
||||
depth, w, h);
|
||||
}
|
||||
|
||||
public Flob centerFlob(FlobSet into, ZZCell c, ZZCell handleCell,
|
||||
float fract, Point p, int xalign, int yalign,
|
||||
int depth, Dimension d) {
|
||||
if(d == null) return centerFlob(into, c, handleCell, fract, p, xalign,
|
||||
yalign, depth);
|
||||
int x, y;
|
||||
x = p.x - d.width/2; y = p.y - d.height/2;
|
||||
|
||||
if(xalign < 0) x = p.x;
|
||||
if(xalign > 0) x = p.x - d.width;
|
||||
if(yalign < 0) y = p.y;
|
||||
if(yalign > 0) y = p.y - d.height;
|
||||
p("centerFlob "+p+" "+d+" at "+x+" "+y+" align "+xalign+" "+yalign);
|
||||
return makeFlob(into, c, handleCell, fract, x, y,
|
||||
depth, d.width, d.height);
|
||||
}
|
||||
public Flob centerFlob(FlobSet into, ZZCell c, ZZCell handleCell,
|
||||
float fract, Point p, int xalign, int yalign, int depth) {
|
||||
int x, y;
|
||||
|
||||
FText ftxt = getFText(c.getRootclone(), getScale(fract));
|
||||
int w = FText.Part.width(ftxt.parts) + margins[0]*2;
|
||||
int h = FText.Part.height(ftxt.parts) + margins[1]*2;
|
||||
|
||||
x = p.x - w/2; y = p.y - h/2;
|
||||
if(xalign < 0) x = p.x;
|
||||
if(xalign > 0) x = p.x - w;
|
||||
if(yalign < 0) y = p.y;
|
||||
if(yalign > 0) y = p.y - h;
|
||||
p("centerFlob "+p+" at "+x+" "+y+" "+w+" "+h+" align "+xalign+" "+yalign);
|
||||
|
||||
return getFlob(into, c, ftxt, x, y, depth, w, h);
|
||||
}
|
||||
}
|
||||
|
||||
// vim: set syntax=java :
|
||||
253
Java/flob/FTextLayouter.zob
Normal file
253
Java/flob/FTextLayouter.zob
Normal file
@@ -0,0 +1,253 @@
|
||||
/*
|
||||
FTextLayouter.java
|
||||
*
|
||||
* Copyright (c) 1999-2000, Ted Nelson and Tuomas Lukka
|
||||
*
|
||||
* You may use and distribute under the terms of either the GNU Lesser
|
||||
* General Public License, either version 2 of the license or,
|
||||
* at your choice, any later version. Alternatively, you may use and
|
||||
* distribute under the terms of the XPL.
|
||||
*
|
||||
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
|
||||
* the licenses.
|
||||
*
|
||||
* This software 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 README
|
||||
* file for more details.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Written by Benjamin Fallenstein
|
||||
*/
|
||||
|
||||
package org.gzigzag;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.util.*;
|
||||
|
||||
/** A layouter for flowing formatted text in a fixed-width rectangle.
|
||||
* @see FText
|
||||
*/
|
||||
|
||||
public class FTextLayouter implements ZOb {
|
||||
public static final String rcsid = "$Id: FTextLayouter.zob,v 1.10 2001/03/30 16:19:37 bfallenstein Exp $";
|
||||
public static boolean dbg = false;
|
||||
static final void p(String s) { if(dbg) System.out.println(s); }
|
||||
static final void pa(String s) { System.out.println(s); }
|
||||
|
||||
public FTextLayouter() {}
|
||||
public FTextLayouter(boolean firstCap) { this.firstCap = firstCap; }
|
||||
|
||||
STRUCTPARAMS {
|
||||
/** Capitalize any letter after two spaces.
|
||||
* This allows simple rearrangement of text without having
|
||||
* to think about capitalization at all times by ending
|
||||
* each sentence with the period/question/... and two spaces.
|
||||
* XXX Maybe this shouldn't be here after all - maybe
|
||||
* separate FText.Part firstcap completely from rendering
|
||||
* to a separate call??
|
||||
*/
|
||||
boolean firstCap
|
||||
= true;
|
||||
|
||||
}
|
||||
|
||||
/** (Internal convenience) Place a number of lines from an array,
|
||||
* given first and last line.
|
||||
*/
|
||||
void placeLines(FlobSet into,
|
||||
FText.Part[][] lines,
|
||||
int[] heights,
|
||||
Rectangle rect,
|
||||
int first,
|
||||
int last,
|
||||
int depth,
|
||||
boolean cursors,
|
||||
Flob fparent) {
|
||||
int y = rect.y, maxx = rect.x + rect.width;
|
||||
p("FTextLayouter placeLines first "+first+" last "+last+" length "+lines.length);
|
||||
|
||||
Renderable prev = null;
|
||||
for(int linenr=first; linenr<=last; linenr++) {
|
||||
FText.Part[] line = lines[linenr];
|
||||
int x = rect.x;
|
||||
y += heights[linenr];
|
||||
|
||||
for(int partnr = 0; partnr<line.length; partnr++) {
|
||||
FText.Part part = line[partnr];
|
||||
int h = part.height(), w = part.width();
|
||||
|
||||
prev = part.rend(x, y-h, depth, prev);
|
||||
if(prev instanceof SplitCellFlob1) {
|
||||
SplitCellFlob1 cur = (SplitCellFlob1)prev;
|
||||
if(cursors) addCurs(into, cur);
|
||||
cur.fg = part.fg; // makes them depth-aware if part.fg is null
|
||||
}
|
||||
if(into!=null) {
|
||||
if(prev instanceof Flob) {
|
||||
Flob f = (Flob)prev;
|
||||
if(fparent != null) f.setParent(fparent);
|
||||
if(f.x + f.w > rect.x + rect.width) {
|
||||
p("FTL clip: "+f.x+" "+f.w+" in "+rect.x+" "+rect.width+" at "+f.c);
|
||||
f.w = rect.x + rect.width - f.x;
|
||||
if(f instanceof SplitCellFlob1)
|
||||
((SplitCellFlob1)f).doClip = true;
|
||||
}
|
||||
if(f.w < 0) f.w = 0;
|
||||
}
|
||||
into.add(prev);
|
||||
}
|
||||
|
||||
x += w;
|
||||
if(x > maxx) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** (Internal convenience) Find the correct span of lines to layout.
|
||||
* Returns an array with two ints: the last line number and the height.
|
||||
*/
|
||||
int[] layout(FText.Part[][] lines,
|
||||
int[] heights,
|
||||
int start,
|
||||
int dir,
|
||||
int maxh) {
|
||||
int height = 0, i = start;
|
||||
for(; i>=0 && i<lines.length; i+=dir) {
|
||||
int lineh = FText.Part.height(lines[i]);
|
||||
heights[i] = lineh;
|
||||
if(height + lineh > maxh) return new int[] { i-dir, height };
|
||||
height += lineh;
|
||||
}
|
||||
return new int[] { i-dir, height };
|
||||
}
|
||||
|
||||
|
||||
public Rectangle place(FlobSet into, FText txt, Rectangle rect,
|
||||
int direction, int initY,
|
||||
int middleoffs,
|
||||
boolean cursors) {
|
||||
return place(into, txt, rect, 100,
|
||||
direction, initY, middleoffs, cursors, (Flob)null);
|
||||
}
|
||||
|
||||
/** To be deprecated -- DON'T USE! */
|
||||
public Rectangle place(FlobSet into, FText txt, Rectangle rect,
|
||||
int direction, int initY,
|
||||
int middleoffs,
|
||||
boolean cursors,
|
||||
boolean[] beginningSentence) {
|
||||
return place(into, txt, rect, 100,
|
||||
direction, initY, middleoffs, cursors, (Flob)null);
|
||||
}
|
||||
|
||||
/** To be deprecated -- DON'T USE! */
|
||||
public Rectangle place(FlobSet into, FText txt, Rectangle rect,
|
||||
int depth,
|
||||
int direction, int initY,
|
||||
int middleoffs,
|
||||
boolean cursors,
|
||||
boolean[] beginningSentence) {
|
||||
return place(into, txt, rect, depth,
|
||||
direction, initY, middleoffs, cursors, (Flob)null);
|
||||
}
|
||||
|
||||
public Rectangle place(FlobSet into, FText txt, Rectangle rect,
|
||||
int depth,
|
||||
int direction, int initY,
|
||||
int middleoffs,
|
||||
boolean cursors) {
|
||||
return place(into, txt, rect, depth,
|
||||
direction, initY, middleoffs, cursors, (Flob)null);
|
||||
}
|
||||
|
||||
/** Place a piece of formatted text into a fixed-width rectangle.
|
||||
* @param into The flobset to place the text into.
|
||||
* @param txt The formatted text object
|
||||
* @param rect The rectangle to fit things into. This is used for
|
||||
* both stopping rendering at the upper and lower edges
|
||||
* and for the margin widths.
|
||||
* (XXX How to i18nize this for other directions?!?!)
|
||||
* @param depth The depth at which to place the flobs.
|
||||
* @param direction The direction we're moving.
|
||||
* 0 = starting from the middle of a paragraph,
|
||||
* 1 = down, -1 = up
|
||||
* @param initY The y coordinate to place the middle/first/last line
|
||||
* of text at, depending on direction.
|
||||
* @param middleoffs If direction==0, the offset that should be at initY.
|
||||
* @param cursors Whether to draw cursors.
|
||||
* @param fparent The flob parent.
|
||||
*/
|
||||
public Rectangle place(FlobSet into, FText txt, Rectangle rect,
|
||||
int depth,
|
||||
int direction, int initY,
|
||||
int middleoffs,
|
||||
boolean cursors,
|
||||
Flob fparent) {
|
||||
if(firstCap) txt.capitalize();
|
||||
FText.Part[][] lines = txt.getLines(rect.width);
|
||||
if(lines.length == 0)
|
||||
return new Rectangle(rect.x, initY, rect.width, 0);
|
||||
|
||||
/** The height of each line. */
|
||||
int[] heights = new int[lines.length];
|
||||
|
||||
/** The first and last lines to place. */
|
||||
int first, last;
|
||||
|
||||
Rectangle res;
|
||||
|
||||
if(direction < 0) {
|
||||
last = lines.length-1;
|
||||
int[] lay = layout(lines, heights, last, -1,
|
||||
initY-rect.y);
|
||||
|
||||
|
||||
first = lay[0]; last = lines.length-1;
|
||||
res = new Rectangle(rect.x, initY-lay[1], rect.width, lay[1]);
|
||||
} else if(direction > 0) {
|
||||
first = 0;
|
||||
int[] lay = layout(lines, heights, first, 1,
|
||||
rect.y + rect.height - initY);
|
||||
last = lay[0];
|
||||
res = new Rectangle(rect.x, initY, rect.width, lay[1]);
|
||||
} else {
|
||||
int middle = FText.findLine(lines, middleoffs);
|
||||
// Make it the middle of the middle line.
|
||||
initY -= FText.Part.height(lines[middle])/2;
|
||||
|
||||
int[] lay1 = layout(lines, heights, middle-1, -1,
|
||||
rect.y + rect.height - initY);
|
||||
int[] lay2 = layout(lines, heights, middle, 1, initY-rect.y);
|
||||
|
||||
first = lay1[0]; last = lay2[0];
|
||||
res = new Rectangle(rect.x, initY-lay1[1], rect.width,
|
||||
lay1[1]+lay2[1]);
|
||||
}
|
||||
|
||||
placeLines(into, lines, heights, res, first, last, depth,
|
||||
cursors, fparent);
|
||||
return res;
|
||||
}
|
||||
|
||||
// XXX make more efficient: do cursor search only for parent sf
|
||||
public static void addCurs(FlobSet into, SplitCellFlob1 sf) {
|
||||
|
||||
Enumeration e = ZZCursorReal.getPointers(sf.getCell());
|
||||
while(e.hasMoreElements()) {
|
||||
ZZCell c = (ZZCell)e.nextElement();
|
||||
|
||||
int ind = ZZCursorReal.getOffs(c);
|
||||
if(ind == ZZCursorReal.NO_OFFSET) continue;
|
||||
if(!(ind >= sf.start && ind <= sf.start + sf.n))
|
||||
continue;
|
||||
int x = sf.getStrX(ind);
|
||||
if(x >= 0 && into != null)
|
||||
into.add(new LineDecor(x, sf.y, x, sf.y+sf.h,
|
||||
Color.black, sf.d));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// vim: set syntax=java :
|
||||
202
Java/flob/Flob.java
Normal file
202
Java/flob/Flob.java
Normal file
@@ -0,0 +1,202 @@
|
||||
/*
|
||||
Flob.java
|
||||
*
|
||||
* Copyright (c) 2000, Ted Nelson and Tuomas Lukka
|
||||
*
|
||||
* You may use and distribute under the terms of either the GNU Lesser
|
||||
* General Public License, either version 2 of the license or,
|
||||
* at your choice, any later version. Alternatively, you may use and
|
||||
* distribute under the terms of the XPL.
|
||||
*
|
||||
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
|
||||
* the licenses.
|
||||
*
|
||||
* This software 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 README
|
||||
* file for more details.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Written by Tuomas Lukka
|
||||
*/
|
||||
package org.gzigzag;
|
||||
import java.util.*;
|
||||
import java.awt.*;
|
||||
|
||||
/** An abstract class to represent a flob shown on screen.
|
||||
* Flobs are constant read-only objects like Strings.
|
||||
* <p>
|
||||
* Flobs should be able to render themselves quickly for animations;
|
||||
* caching relevant
|
||||
* information in this structure is therefore a good idea.
|
||||
* <p>
|
||||
* The minimal flob implementation simply implements the
|
||||
* render(Graphics, int, int, int, int, int) method.
|
||||
*/
|
||||
|
||||
public abstract class Flob extends Renderable {
|
||||
public static final String rcsid = "$Id: Flob.java,v 1.18 2001/03/17 23:08:23 bfallenstein Exp $";
|
||||
public int x, y, w, h;
|
||||
|
||||
/** The identifier of the place this flob is.
|
||||
* This is used to create a possibly hierarchical
|
||||
* system so that animation doesn't confuse two
|
||||
* instances of the same cell.
|
||||
* deprecated Use setParent() / getParent().
|
||||
*/
|
||||
public String flobPath = "";
|
||||
|
||||
/** The cell associated with this flob.
|
||||
* This may be set to null for things that are - well - just
|
||||
* things rendered. But those should be in a minority always.
|
||||
*/
|
||||
public ZZCell c;
|
||||
|
||||
/** The flob we are interpolating with.
|
||||
* Storing it here is a pure speed hack: in reality it'd belong in
|
||||
* a hashtable somewhere. But this is crucial for the frame rate.
|
||||
*/
|
||||
protected Flob interpTo;
|
||||
|
||||
/** The parent of this flob.
|
||||
* Only flobs with no parents and flobs whose parents are interpolated
|
||||
* to each other are interpolated to each other.
|
||||
* <p>
|
||||
* set/get by setParent() / getParent()
|
||||
*/
|
||||
private Flob flobparent = null;
|
||||
|
||||
/** The applitude that has placed this flob.
|
||||
* When the views of different applitudes are combined, this field is set
|
||||
* by the combining view. When a flob is clicked upon, the field is read,
|
||||
* the applitude is made the window's prefered applitude, and the mouse
|
||||
* binding is executed according to the bindings of that applitude.
|
||||
*/
|
||||
public ZZCell applitude = null;
|
||||
|
||||
public void setParent(Flob p) {
|
||||
flobparent = p;
|
||||
flobPath = p.flobPath + "-" + p;
|
||||
}
|
||||
|
||||
public Flob getParent() { return flobparent; }
|
||||
|
||||
/** Return true if a box should be drawn around this flob.
|
||||
*/
|
||||
public boolean needsBox() { return false; }
|
||||
|
||||
public Flob(int x, int y, int d, int w, int h, ZZCell c) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.w = w;
|
||||
this.h = h;
|
||||
this.d = d;
|
||||
this.c = c;
|
||||
}
|
||||
|
||||
/** Get a point aligned in a cell.
|
||||
* getPoint(-1, 0) --> left/middle
|
||||
* getPoint(1, 1) --> right/lower
|
||||
* etc. -- middle means visual center (getCenter()).
|
||||
*/
|
||||
public Point getPoint(Point p, int xa, int ya) {
|
||||
getCenter(p);
|
||||
if(xa < 0) p.x = x;
|
||||
if(xa > 0) p.x = x+w;
|
||||
if(ya < 0) p.y = y;
|
||||
if(ya > 0) p.y = y+h;
|
||||
return p;
|
||||
}
|
||||
public Point getPoint(int xo, int yo) {
|
||||
return getPoint(new Point(), xo, yo);
|
||||
}
|
||||
|
||||
/** Get the visual center of this flob.
|
||||
*/
|
||||
public Point getCenter(Point p) {
|
||||
p.x = x+w/2; p.y = y+h/2;
|
||||
return p;
|
||||
}
|
||||
|
||||
/** Get the visual center of this flob.
|
||||
*/
|
||||
public Point getCenter() {
|
||||
return getCenter(new Point());
|
||||
}
|
||||
|
||||
/** Render this flob at the given coordinates.
|
||||
* Default: render nothing.
|
||||
* You may override either this function or one or both of
|
||||
* render(Graphics) and renderInterp(Graphics, float).
|
||||
*/
|
||||
public void render(Graphics g, int mx, int my, int md,
|
||||
int mw, int mh) {
|
||||
}
|
||||
|
||||
/** Render this flob.
|
||||
* May be overridden; default implementation uses render(g, x, y, w, h, d);
|
||||
*/
|
||||
public void render(Graphics g) {
|
||||
render(g, x, y, d, w, h);
|
||||
}
|
||||
/** Render an interpolated version of this flob.
|
||||
* Default implementation uses render(g, x, y, w, h, d) with linearly
|
||||
* interpolated coordinates.
|
||||
*/
|
||||
public void renderInterp(Graphics g, float fract) {
|
||||
Flob r = interpTo;
|
||||
if(r==null) return;
|
||||
render(g,
|
||||
(int)(x + fract*(r.x-x)),
|
||||
(int)(y + fract*(r.y-y)),
|
||||
(int)(d + fract*(r.d-d)),
|
||||
(int)(w + fract*(r.w-w)),
|
||||
(int)(h + fract*(r.h-h))
|
||||
);
|
||||
}
|
||||
|
||||
/** If there is a XOR-cursor associated with this flob,
|
||||
* render it.
|
||||
* This can be made to e.g. follow the mouse cursor to
|
||||
* show where the click would land.
|
||||
* Default implementation: do nothing, return
|
||||
* <pre> hit(x,y)!=null </pre>
|
||||
* @return Whether the coordinates hit this flob, i.e.
|
||||
* whether the system should stop looking for the
|
||||
* XOR curser.
|
||||
*/
|
||||
public boolean renderXOR(Graphics g, int x, int y) {
|
||||
return hit(x,y) != null;
|
||||
}
|
||||
|
||||
/** Whether it would make visually sense to interpolate
|
||||
* this flob.
|
||||
* Default implementation: whether the sum of the squares of
|
||||
* the differences of the coordinates and widths is more than 100.
|
||||
* Not a terribly useful measure but good enough.
|
||||
*/
|
||||
public boolean isInterpUseful() {
|
||||
Flob r = interpTo;
|
||||
if(r==null) return false;
|
||||
return (r.x - x) * (r.x - x) +
|
||||
(r.y - y) * (r.y - y) +
|
||||
(r.w - w) * (r.w - w) +
|
||||
(r.h - h) * (r.h - h) > 100;
|
||||
}
|
||||
|
||||
|
||||
/** Returns an object telling what was hit.
|
||||
* Default implementation: returns null.
|
||||
*/
|
||||
public Object hit(int x, int y) { return null; }
|
||||
|
||||
/** A convenience routine to check whether a point
|
||||
* is inside the defining rectangle.
|
||||
* If the flob is (as many are) rectangular, this routine can
|
||||
* be used to check the hit.
|
||||
*/
|
||||
public final boolean insideRect(int x0, int y0) {
|
||||
return x0 >= x && y0 >= y && x0 < x+w && y0 < y+h;
|
||||
}
|
||||
}
|
||||
39
Java/flob/FlobDecorator.java
Normal file
39
Java/flob/FlobDecorator.java
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
FlobDecorator.java
|
||||
*
|
||||
* Copyright (c) 2000, Ted Nelson and Tuomas Lukka
|
||||
*
|
||||
* You may use and distribute under the terms of either the GNU Lesser
|
||||
* General Public License, either version 2 of the license or,
|
||||
* at your choice, any later version. Alternatively, you may use and
|
||||
* distribute under the terms of the XPL.
|
||||
*
|
||||
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
|
||||
* the licenses.
|
||||
*
|
||||
* This software 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 README
|
||||
* file for more details.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Written by Tuomas Lukka
|
||||
*/
|
||||
|
||||
package org.gzigzag;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.util.*;
|
||||
|
||||
/** An interface for classes that decorate FlobSets by drawing connections
|
||||
* or so.
|
||||
*/
|
||||
|
||||
public interface FlobDecorator {
|
||||
String rcsid = "$Id: FlobDecorator.java,v 1.6 2000/10/26 18:09:29 tjl Exp $";
|
||||
/** Add Renderables or Flobs to the given flobset,
|
||||
* based on the flobs already in there.
|
||||
*/
|
||||
void decorate(FlobSet f, String path, ZZCell view);
|
||||
}
|
||||
89
Java/flob/FlobFactory.java
Normal file
89
Java/flob/FlobFactory.java
Normal file
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
RasterFlobFactory.java
|
||||
*
|
||||
* Copyright (c) 2000, Ted Nelson and Tuomas Lukka
|
||||
*
|
||||
* You may use and distribute under the terms of either the GNU Lesser
|
||||
* General Public License, either version 2 of the license or,
|
||||
* at your choice, any later version. Alternatively, you may use and
|
||||
* distribute under the terms of the XPL.
|
||||
*
|
||||
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
|
||||
* the licenses.
|
||||
*
|
||||
* This software 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 README
|
||||
* file for more details.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Written by Tuomas Lukka
|
||||
*/
|
||||
package org.gzigzag;
|
||||
import java.util.*;
|
||||
import java.awt.*;
|
||||
|
||||
/** An interface to generate flobs to put in a raster.
|
||||
* This is for abstracting out what the cells look like.
|
||||
* The "CellViews" in ZZDefaultSpace corresponds to classes
|
||||
* implementing this interface.
|
||||
*/
|
||||
|
||||
public interface FlobFactory {
|
||||
String rcsid = "$Id$";
|
||||
/** Get the default dimensions for the given cell and fraction.
|
||||
* @param c The cell. If null, the default dimensions overall are returned.
|
||||
* @param fract The magnification fraction.
|
||||
*/
|
||||
Dimension getSize(ZZCell c, float fract);
|
||||
|
||||
/** Create a 2-D flob.
|
||||
* This call creates the flob and places it into the given FlobSet.
|
||||
* @param c The cell for the flob
|
||||
* @param handleCell The cell from which to show e.g. cursor.
|
||||
* This mechanism may change.
|
||||
*/
|
||||
Flob makeFlob(FlobSet f,
|
||||
ZZCell c, ZZCell handleCell,
|
||||
float fract, int x, int y, int d, int w, int h);
|
||||
|
||||
/** Place a flob.
|
||||
* Here, the size can vary freely: the flob is placed so that
|
||||
* the point (x,y) is at (xfract, yfract) in the unit coordinate
|
||||
* system stretched to fit inside. E.g. if (xfract, yfract)==(0,1)
|
||||
* then (x,y) will be the lower left corner.
|
||||
* The reason for this call is that it may be almost twice as fast
|
||||
* as doing getSize() and makeFlob() since both may have to do some
|
||||
* of the same calculations (e.g. line breaking).
|
||||
* <p>
|
||||
* This call should give the same results as
|
||||
* <pre>
|
||||
* Dimension d = getSize(c, fract);
|
||||
* return makeFlob(c, fract,
|
||||
* (int)(x-xfract*d.width),
|
||||
* (int)(y-yfract*d.height),
|
||||
* depth, d.width, d.height);
|
||||
* </pre>
|
||||
*/
|
||||
Flob placeFlob(FlobSet f,
|
||||
ZZCell c, ZZCell handleCell,
|
||||
float fract,
|
||||
int x, int y, int depth,
|
||||
float xfract, float yfract);
|
||||
|
||||
|
||||
// should call centerFlob(..., null)
|
||||
Flob centerFlob(FlobSet f,
|
||||
ZZCell c, ZZCell handleCell,
|
||||
float fract, Point p, int xalign, int yalign,
|
||||
int depth);
|
||||
|
||||
// if d==null, use what getSize would return
|
||||
Flob centerFlob(FlobSet f,
|
||||
ZZCell c, ZZCell handleCell,
|
||||
float fract, Point p, int xalign, int yalign,
|
||||
int depth, Dimension d);
|
||||
}
|
||||
|
||||
|
||||
521
Java/flob/FlobSet.java
Normal file
521
Java/flob/FlobSet.java
Normal file
@@ -0,0 +1,521 @@
|
||||
/*
|
||||
FlobSet.java
|
||||
*
|
||||
* Copyright (c) 2000, Ted Nelson and Tuomas Lukka
|
||||
*
|
||||
* You may use and distribute under the terms of either the GNU Lesser
|
||||
* General Public License, either version 2 of the license or,
|
||||
* at your choice, any later version. Alternatively, you may use and
|
||||
* distribute under the terms of the XPL.
|
||||
*
|
||||
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
|
||||
* the licenses.
|
||||
*
|
||||
* This software 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 README
|
||||
* file for more details.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Written by Tuomas Lukka
|
||||
*/
|
||||
package org.gzigzag;
|
||||
import java.util.*;
|
||||
import java.awt.*;
|
||||
|
||||
/** A set of flobs, i.e.things that are rendered to screen associated
|
||||
* with cells.
|
||||
* Flobs are stored with depths, which are stably sorted in the end
|
||||
* so that the flobs placed later are on top.
|
||||
*/
|
||||
|
||||
public class FlobSet implements ZZScene {
|
||||
public static final String rcsid = "$Id: FlobSet.java,v 1.41.2.1 2002/03/07 21:02:41 bfallenstein Exp $";
|
||||
|
||||
public static final boolean dbg = true;
|
||||
static final void p(String s) { if(dbg) System.out.println(s); }
|
||||
static final void pa(String s) { System.out.println(s); }
|
||||
|
||||
Dimension size;
|
||||
public Dimension getSize() {
|
||||
return size;
|
||||
}
|
||||
Color fg, bg;
|
||||
Component cpt;
|
||||
|
||||
public SceneFlob sflob = null;
|
||||
public BoxType box = new SimpleBoxType();
|
||||
|
||||
public FlobSet(Dimension size, Color foreground, Color background,
|
||||
Component cpt) {
|
||||
this.size = size;
|
||||
this.bg = background;
|
||||
this.fg = foreground;
|
||||
this.cpt = cpt;
|
||||
}
|
||||
public Component getComponent() { return cpt; }
|
||||
public Color getForeground() { return fg; }
|
||||
public Color getBackground() { return bg; }
|
||||
|
||||
|
||||
private Hashtable c2ph;
|
||||
private Hashtable nph; // Hashtable for flobs w/o parents
|
||||
|
||||
private final Hashtable getPH(Flob parent) {
|
||||
if(parent == null)
|
||||
return nph;
|
||||
Hashtable res = (Hashtable)c2ph.get(parent);
|
||||
if(res == null)
|
||||
c2ph.put(parent, res=new Hashtable());
|
||||
return res;
|
||||
}
|
||||
|
||||
private int nflobs;
|
||||
private Flob[] flobs = new Flob[30];
|
||||
boolean fsorted = false;
|
||||
boolean ftagged = false;
|
||||
|
||||
|
||||
private int nrend;
|
||||
/** Decorations.
|
||||
*/
|
||||
private Renderable[] rends = new Renderable[10];
|
||||
boolean rsorted = false;
|
||||
|
||||
private int maxdepth = 0;
|
||||
|
||||
public void add(Renderable r) {
|
||||
// Check: if it happens to be a flob, then put
|
||||
// it as a flob.
|
||||
if(r instanceof Flob) {
|
||||
add((Flob)r);
|
||||
return;
|
||||
}
|
||||
|
||||
if(r.d > maxdepth) maxdepth = r.d;
|
||||
if(nrend >= rends.length) {
|
||||
Renderable[] n = new Renderable[nrend + 50];
|
||||
System.arraycopy(rends, 0, n, 0, nrend);
|
||||
rends = n;
|
||||
}
|
||||
rends[nrend++] = r;
|
||||
rsorted = false;
|
||||
}
|
||||
|
||||
/** Add a flob into the flobset.
|
||||
* Note that flobPath might not be set yet.
|
||||
* It is therefore used only when the flobs are being sorted.
|
||||
*/
|
||||
public void add(Flob f) {
|
||||
// p("AddFlob "+f.x+" "+f.y+" "+f.w+" "+f.h+" "+f.d);
|
||||
if(f.d <= 0)
|
||||
throw new ZZError("Negative or zero depth for flob!");
|
||||
if(f.d > maxdepth) maxdepth = f.d;
|
||||
// if(f.c != null)
|
||||
// getPH(f.flobPath).put(f.c, f);
|
||||
if(nflobs >= flobs.length) {
|
||||
Flob[] n = new Flob[nflobs + 100];
|
||||
System.arraycopy(flobs, 0, n, 0, nflobs);
|
||||
flobs = n;
|
||||
}
|
||||
flobs[nflobs++] = f;
|
||||
fsorted = false;
|
||||
ftagged = false;
|
||||
if(sflob != null && f instanceof SceneFlob)
|
||||
((SceneFlob)f).parent = sflob;
|
||||
}
|
||||
|
||||
public final void tag() {
|
||||
if(ftagged) return;
|
||||
c2ph = new Hashtable(); nph = new Hashtable();
|
||||
for(int i=0; i<nflobs; i++) {
|
||||
Flob f = flobs[i];
|
||||
if(f.c != null) {
|
||||
Hashtable h = getPH(f.getParent());
|
||||
Object o = h.get(f.c);
|
||||
if(o == null) {
|
||||
h.put(f.c, f);
|
||||
} else if(o instanceof Flob) {
|
||||
Vector v = new Vector();
|
||||
v.addElement(o);
|
||||
v.addElement(f);
|
||||
h.put(f.c, v);
|
||||
} else {
|
||||
((Vector)o).addElement(f);
|
||||
}
|
||||
}
|
||||
}
|
||||
ftagged = true;
|
||||
}
|
||||
|
||||
public final void sort() { sortf(); sortr(); }
|
||||
public final void sortf() {
|
||||
if(fsorted) return;
|
||||
// pa("SORTING");
|
||||
// dump();
|
||||
Renderable.depthSort(flobs, nflobs);
|
||||
fsorted = true;
|
||||
// dump();
|
||||
}
|
||||
public final void sortr() {
|
||||
if(rsorted) return;
|
||||
Renderable.depthSort(rends, nrend);
|
||||
rsorted = true;
|
||||
}
|
||||
|
||||
protected void depthColor(Graphics g, int depth) {
|
||||
// XXX Foreground adjustable?
|
||||
if(depth > maxdepth)
|
||||
throw new ZZError("Too strange. "+depth+" "+maxdepth);
|
||||
int fract = (256*(depth-1)) / (maxdepth + maxdepth / 10);
|
||||
Color ncol = ZZUtil.mix(fg, bg, fract);
|
||||
g.setColor(ncol);
|
||||
// p("Color: "+fract+" "+d+" "+maxdepth+" "+ncol);
|
||||
}
|
||||
|
||||
public void render(Graphics g) {
|
||||
render(g, g);
|
||||
}
|
||||
public void render(Graphics g, Graphics orig) {
|
||||
|
||||
// ZZDrawing.instance.setAlpha(g, (float)0.5);
|
||||
ZZDrawing.instance.setDefaults(g);
|
||||
ZZDrawing.instance.setQuality(g);
|
||||
|
||||
int f=nflobs-1;
|
||||
int r=nrend-1;
|
||||
int oldd = -1;
|
||||
sort();
|
||||
// p("StartColors");
|
||||
while(f >= 0 || r >= 0) {
|
||||
// Stagger the two arrays. Always render decorations of the same
|
||||
// depth last
|
||||
while(f >= 0 &&
|
||||
( r < 0 || rends[r].d <= flobs[f].d)) {
|
||||
if(flobs[f].d != oldd)
|
||||
depthColor(g, oldd = flobs[f].d);
|
||||
if(!flobs[f].needsBox())
|
||||
flobs[f--].render(g, orig);
|
||||
else {
|
||||
Flob fl = flobs[f--];
|
||||
box.renderBg(g, fl);
|
||||
fl.render(g, orig);
|
||||
box.renderFrame(g, fl);
|
||||
}
|
||||
}
|
||||
while(r >= 0 &&
|
||||
( f < 0 || rends[r].d > flobs[f].d)) {
|
||||
if(rends[r].d != oldd)
|
||||
depthColor(g, oldd = rends[r].d);
|
||||
rends[r--].render(g, orig);
|
||||
}
|
||||
}
|
||||
renderDC(g);
|
||||
}
|
||||
|
||||
FlobSet interpPrepared = null;
|
||||
public void renderInterp(Graphics g, ZZScene other0,
|
||||
float fract) {
|
||||
|
||||
ZZDrawing.instance.setDefaults(g);
|
||||
|
||||
sort();
|
||||
FlobSet other = (FlobSet)other0;
|
||||
if(interpPrepared != other) {
|
||||
prepareInterp(other);
|
||||
}
|
||||
renderInterp(g, fract);
|
||||
}
|
||||
|
||||
public void renderInterp(Graphics g, float fract) {
|
||||
int oldd = -1;
|
||||
for(int i=nflobs-1; i>=0; i--) {
|
||||
if(flobs[i].d != oldd)
|
||||
depthColor(g, oldd = flobs[i].d);
|
||||
if(flobs[i].interpTo == null || !flobs[i].needsBox())
|
||||
flobs[i].renderInterp(g, fract);
|
||||
else {
|
||||
// XXX the interpolation path isn't necessarily linear!
|
||||
box.renderBg(g, flobs[i], fract);
|
||||
flobs[i].renderInterp(g, fract);
|
||||
box.renderFrame(g, flobs[i], fract);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isInterpUseful(ZZScene other0) {
|
||||
FlobSet other = (FlobSet)other0;
|
||||
return prepareInterp(other);
|
||||
}
|
||||
|
||||
/** Find flobs for this parent and cell.
|
||||
* @returns null if no flobs are found (empty array would be inefficient)
|
||||
*/
|
||||
public Flob[] findFlobs(Flob parent, ZZCell c) {
|
||||
tag();
|
||||
Hashtable hash = getPH(parent);
|
||||
Object o = hash.get(c);
|
||||
if(o == null) return null;
|
||||
else if(o instanceof Flob) return new Flob[] { (Flob)o };
|
||||
else if(o instanceof Flob[]) return (Flob[])o;
|
||||
|
||||
// Now, we have a Vector. Convert to array.
|
||||
Vector v = (Vector)o;
|
||||
Flob[] res = new Flob[v.size()];
|
||||
for(int i=0; i<res.length; i++) res[i] = (Flob)v.elementAt(i);
|
||||
|
||||
// tag() only puts Vectors. Now put the converted array.
|
||||
hash.put(c, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
/** True if from's center is nearer to test's than other's. */
|
||||
static boolean isNearer(Flob from, Flob test, Flob other) {
|
||||
int fx = from.x + from.w/2, fy = from.y + from.h/2;
|
||||
int tx = test.x + test.w/2, ty = test.y + test.h/2;
|
||||
int ox = other.x + other.w/2, oy = other.y + other.h/2;
|
||||
return ((fx-tx)*(fx-tx) + (fy-ty)*(fy-ty))
|
||||
< ((fx-ox)*(fx-ox) + (fy-oy)*(fy-oy));
|
||||
}
|
||||
|
||||
|
||||
/** Find the flob in this flobset which is nearest to a flob in another
|
||||
* flobset -- i.e., f is supposed NOT to be in this flobset. Distances
|
||||
* are measured center to center.
|
||||
* @param f The flob to search from -- should NOT be in this set.
|
||||
* @param parent The parent of the flob to find -- must be in THIS set.
|
||||
*/
|
||||
public Flob findNearest(Flob f, Flob parent) {
|
||||
Flob[] flobs = findFlobs(parent, f.c);
|
||||
if(flobs == null) return null;
|
||||
Flob result = null;
|
||||
for(int i=0; i<flobs.length; i++) {
|
||||
Flob g = flobs[i];
|
||||
if(result == null || isNearer(f, g, result))
|
||||
result = g;
|
||||
}
|
||||
if(result != null) return result;
|
||||
else return null;
|
||||
}
|
||||
|
||||
/** For compatibility
|
||||
* deprecated Use findFlobs, findNearest or something.
|
||||
*/
|
||||
public Flob findFlob(String path, ZZCell c) {
|
||||
Flob[] flobs = findFlobs(null, c);
|
||||
if(flobs == null) return null;
|
||||
for(int i=0; i<flobs.length; i++)
|
||||
if(flobs[i].flobPath.equals(path))
|
||||
return flobs[i];
|
||||
return null;
|
||||
}
|
||||
|
||||
/** Prepare for interpolation
|
||||
* with another flobset. Usually
|
||||
* used only internally.
|
||||
*/
|
||||
boolean prepareInterp(FlobSet f2) {
|
||||
if(interpPrepared == f2) return true;
|
||||
// p("Flobset: prepareInterp "+this+" "+f2);
|
||||
boolean useful = false;
|
||||
for(int i=0; i<f2.nflobs; i++)
|
||||
f2.flobs[i].interpTo = null;
|
||||
// First set to null -- avoid animation errors
|
||||
for(int i=0; i<nflobs; i++) flobs[i].interpTo = null;
|
||||
for(int iter=0; iter<5; iter++) {
|
||||
for(int i=0; i<nflobs; i++) {
|
||||
if(flobs[i].c == null) continue;
|
||||
Flob parent = flobs[i].getParent();
|
||||
Flob f = f2.findNearest(flobs[i],
|
||||
parent != null ? parent.interpTo : null);
|
||||
if(f==null ||
|
||||
(f.interpTo != null && isNearer(f, f.interpTo, flobs[i])) ||
|
||||
(parent != null && parent.interpTo == null)) continue;
|
||||
flobs[i].interpTo = f;
|
||||
f.interpTo = flobs[i];
|
||||
useful = (useful || flobs[i].isInterpUseful());
|
||||
}
|
||||
}
|
||||
f2.interpPrepared = this;
|
||||
interpPrepared = f2;
|
||||
return useful;
|
||||
}
|
||||
|
||||
/** Prepare for interpolation with another flobset,
|
||||
* but only moving given flobs.
|
||||
* Used to effect level-of-detail for SceneFlobs.
|
||||
* Note that this also only modifies the current flobset
|
||||
* and gives the current flobset the pointers...
|
||||
*/
|
||||
public void prepareInterp(FlobSet f2, Flob[] which) {
|
||||
// p("Flobset: prepareInterp LIMITED "+this+" "+f2+" "+which);
|
||||
interpPrepared = f2;
|
||||
for(int i=0; i<nflobs; i++) flobs[i].interpTo = null;
|
||||
for(int i=0; i<which.length; i++) {
|
||||
if(which[i].c == null) continue;
|
||||
// Parents not used here...
|
||||
Flob f = f2.findNearest(which[i], null);
|
||||
if(f==null) continue;
|
||||
which[i].interpTo = f;
|
||||
}
|
||||
}
|
||||
|
||||
public Object getObjectAt(int x, int y) {
|
||||
return getObjectAt(x, y, null);
|
||||
}
|
||||
|
||||
public Object getObjectAt(int x, int y, Flob[] fres) {
|
||||
sortf();
|
||||
for(int i=0; i<nflobs; i++) {
|
||||
Object o = flobs[i].hit(x, y);
|
||||
if(o != null) {
|
||||
if(fres != null) fres[0] = flobs[i];
|
||||
return o;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void renderXOR(Graphics g, int x, int y) {
|
||||
Flob[] which = new Flob[1];
|
||||
Object co = getObjectAt(x, y, which);
|
||||
if(co == null) return;
|
||||
which[0].renderXOR(g, x, y);
|
||||
}
|
||||
|
||||
public void dump() {
|
||||
pa("FlobSet dump: "+nflobs+" "+nrend);
|
||||
for(int i=0; i<flobs.length; i++) {
|
||||
if(flobs[i] == null) {
|
||||
pa(" Flob null!");
|
||||
continue;
|
||||
}
|
||||
pa(" Flob "+flobs[i].x+" "+flobs[i].y+" "+
|
||||
flobs[i].w+" "+flobs[i].h+" "+flobs[i].d+" "+flobs[i]);
|
||||
}
|
||||
for(int i=0; i<rends.length; i++) {
|
||||
if(rends[i] == null) {
|
||||
pa(" Renderable null!");
|
||||
continue;
|
||||
}
|
||||
pa(" Renderable "+ rends[i].d+" "+rends[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/** A callback interface for iterating over the Flobs
|
||||
* in a FlobSet in depth order.
|
||||
*/
|
||||
public static abstract class DepthIter {
|
||||
public void act(Flob[] flobs, int start, int n) {}
|
||||
/* @param in The scene flob all these flobs are in. */
|
||||
public void act(Flob[] flobs, int start, int n, SceneFlob in) {
|
||||
act(flobs, start, n);
|
||||
}
|
||||
}
|
||||
|
||||
/** Iterate a routine over blocks of same-depth flobs.
|
||||
* @param flat Whether to include flobs inside SceneFlobs.
|
||||
*/
|
||||
public void iterDepth(DepthIter di, boolean frontFirst, boolean flat) {
|
||||
if(nflobs <= 0) return;
|
||||
if(flobs == null) throw new Error("NULL FLOBS");
|
||||
if(flobs[0] == null) throw new Error("NULL FIRST FLOB");
|
||||
sortf();
|
||||
if(flobs == null) throw new Error("NULL FLOBS AFTER SORT");
|
||||
if(flobs[0] == null) throw new Error("NULL FIRST FLOB AFTER SORT");
|
||||
if(frontFirst) {
|
||||
int cur = 0; int curd = flobs[0].d;
|
||||
for(int i=0; i<nflobs; i++) {
|
||||
if(flat && flobs[i] instanceof SceneFlob) {
|
||||
di.act(flobs, cur, i-cur, sflob);
|
||||
((SceneFlob)flobs[i]).getFlobSet().iterDepth(di, true, true);
|
||||
cur = i; curd = flobs[i].d;
|
||||
} else if(curd != flobs[i].d ) {
|
||||
di.act(flobs, cur, i-cur, sflob);
|
||||
cur = i;
|
||||
curd = flobs[i].d;
|
||||
}
|
||||
}
|
||||
di.act(flobs, cur, nflobs-cur);
|
||||
} else {
|
||||
int cur = nflobs-1; int curd = flobs[nflobs-1].d;
|
||||
for(int i=nflobs-1; i>=0; i--) {
|
||||
if(flat && flobs[i] instanceof SceneFlob) {
|
||||
di.act(flobs, i+1, cur-i, sflob);
|
||||
((SceneFlob)flobs[i]).getFlobSet().iterDepth(di, true, true);
|
||||
cur = i; curd = flobs[i].d;
|
||||
} if(curd != flobs[i].d) {
|
||||
di.act(flobs, i+1, cur-i, sflob);
|
||||
cur = i;
|
||||
curd = flobs[i].d;
|
||||
}
|
||||
}
|
||||
di.act(flobs, 0, cur+1);
|
||||
}
|
||||
}
|
||||
|
||||
/** Iterate a routine over blocks of same-depth flobs.
|
||||
* Does not include flobs inside SceneFlobs.
|
||||
*/
|
||||
public void iterDepth(DepthIter di, boolean frontFirst) {
|
||||
iterDepth(di, frontFirst, false);
|
||||
}
|
||||
|
||||
DragCursor dc; int dcx, dcy;
|
||||
public void setDragCursor(DragCursor dc, int x, int y) {
|
||||
this.dc = dc; this.dcx = x; this.dcy = y;
|
||||
}
|
||||
public interface DragCursor {
|
||||
boolean accept(Object o);
|
||||
}
|
||||
|
||||
/** Render the current dragCursor.
|
||||
*/
|
||||
private void renderDC(Graphics g) {
|
||||
if(dc == null) return;
|
||||
Flob[] which = new Flob[1];
|
||||
Object co = getObjectAt(dcx, dcy, which);
|
||||
if(co == null) return;
|
||||
if(!dc.accept(co)) return;
|
||||
which[0].renderXOR(g, dcx, dcy);
|
||||
}
|
||||
|
||||
public int fetch(FlobSet from, int x, int y, int d) {
|
||||
return fetch(from, x, y, d, null);
|
||||
}
|
||||
|
||||
/** Fetch the contents of another FlobSet and translate coordinates.
|
||||
* Takes all flobs and rends, adds x, y and do to their coordinates,
|
||||
* and puts them in this set. This is used to combine views.
|
||||
* @param Whenever a flob's applitude field contains null, it is set
|
||||
* to this value (which may be null in itself).
|
||||
* @returns The highest depth used (or d, if there weren't any flobs).
|
||||
*/
|
||||
public int fetch(FlobSet from, int x, int y, int d, ZZCell applitude) {
|
||||
int res = d;
|
||||
for(int i=0; i<from.nflobs; i++) {
|
||||
Flob f = from.flobs[i];
|
||||
f.x += x; f.y += y; f.d += d;
|
||||
if(f.d > res) res = f.d;
|
||||
if(f.applitude == null) f.applitude = applitude;
|
||||
add(f);
|
||||
}
|
||||
for(int i=0; i<from.nrend; i++) {
|
||||
Renderable r = from.rends[i];
|
||||
if(!r.translate(x, y)) continue;
|
||||
r.d += d;
|
||||
if(r.d > res) res = r.d;
|
||||
add(r);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/** Get a new FlobSet like this, just with a different size.
|
||||
* Used to combine views.
|
||||
*/
|
||||
public FlobSet create(Dimension size) {
|
||||
return new FlobSet(size, fg, bg, cpt);
|
||||
}
|
||||
|
||||
}
|
||||
57
Java/flob/FlobView.java
Normal file
57
Java/flob/FlobView.java
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
FlobRaster.java
|
||||
*
|
||||
* Copyright (c) 2000, Ted Nelson and Tuomas Lukka
|
||||
*
|
||||
* You may use and distribute under the terms of either the GNU Lesser
|
||||
* General Public License, either version 2 of the license or,
|
||||
* at your choice, any later version. Alternatively, you may use and
|
||||
* distribute under the terms of the XPL.
|
||||
*
|
||||
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
|
||||
* the licenses.
|
||||
*
|
||||
* This software 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 README
|
||||
* file for more details.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Written by Tuomas Lukka
|
||||
*/
|
||||
package org.gzigzag;
|
||||
import java.util.*;
|
||||
|
||||
/** A fairly general interface for drawing a structure
|
||||
* on the screen using flobs.
|
||||
* The parameters have been read through the ZOb interface so
|
||||
* we don't need to worry about those here.
|
||||
*/
|
||||
|
||||
public interface FlobView {
|
||||
String rcsid = "$Id$";
|
||||
/** Draw a representation of the structure into the FlobSet.
|
||||
* An implementation of this routine will usually place a number
|
||||
* of Flobs and Renderables into
|
||||
* The parameters dims and accursed are redundant but since they
|
||||
* are used so often, it's just good to have them.
|
||||
* @param into The FlobSet to place the flobs and decorations into.
|
||||
* @param fact A factory for constructing flobs. This may be used
|
||||
* or ignored by the FlobRaster. In general, it should
|
||||
* be used to draw the "run-of-the-mill" flobs.
|
||||
* @param view The viewspecs cell in the structure.
|
||||
* @param dims Three first dims
|
||||
* @param accursed The cell that the cursor is on
|
||||
* @see Flob
|
||||
* @see Renderable
|
||||
* @see FlobSet
|
||||
* @see RasterFlobFactory
|
||||
*/
|
||||
void raster(FlobSet into, FlobFactory fact,
|
||||
ZZCell view, String[] dims, ZZCell accursed);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
51
Java/flob/GridGeom.java
Normal file
51
Java/flob/GridGeom.java
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
GridGeom.java
|
||||
*
|
||||
* Copyright (c) 2000, Ted Nelson and Tuomas Lukka
|
||||
*
|
||||
* You may use and distribute under the terms of either the GNU Lesser
|
||||
* General Public License, either version 2 of the license or,
|
||||
* at your choice, any later version. Alternatively, you may use and
|
||||
* distribute under the terms of the XPL.
|
||||
*
|
||||
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
|
||||
* the licenses.
|
||||
*
|
||||
* This software 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 README
|
||||
* file for more details.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Written by Tuomas Lukka
|
||||
*/
|
||||
package org.gzigzag;
|
||||
import java.awt.*;
|
||||
|
||||
/** An object that describes the geometry of a rectangular grid.
|
||||
* The grid is assumed to have a center cell i.e. to have an odd
|
||||
* number of cells.
|
||||
*/
|
||||
|
||||
public abstract class GridGeom {
|
||||
String rcsid = "$Id: GridGeom.java,v 1.1 2000/10/21 23:07:35 tjl Exp $";
|
||||
/** Initialize the sizes of this grid.
|
||||
* @param normalcell The size of a "normal" cell.
|
||||
* @param canvas The size of the whole rectangle this grid is placed
|
||||
* into
|
||||
* @return the number of cells in the grid in X and Y directions.
|
||||
*/
|
||||
public abstract Dimension setSizes(Dimension normalcell, Dimension canvas);
|
||||
/** Returns the rectangle corresponding to the given cell.
|
||||
*/
|
||||
public final Rectangle getCell(int x, int y) {
|
||||
return getCell(x, y, new Rectangle());
|
||||
}
|
||||
/** Returns the rectangle corresponding to the given cell,
|
||||
* placed into the given Rectangle object.
|
||||
*/
|
||||
public abstract Rectangle getCell(int x, int y, Rectangle rect);
|
||||
}
|
||||
|
||||
// vim: set syntax=java :
|
||||
71
Java/flob/ICView.zob
Normal file
71
Java/flob/ICView.zob
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
ICView.zob
|
||||
*
|
||||
* Copyright (c) 1999-2000, Ted Nelson and Tuomas Lukka
|
||||
*
|
||||
* You may use and distribute under the terms of either the GNU Lesser
|
||||
* General Public License, either version 2 of the license or,
|
||||
* at your choice, any later version. Alternatively, you may use and
|
||||
* distribute under the terms of the XPL.
|
||||
*
|
||||
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
|
||||
* the licenses.
|
||||
*
|
||||
* This software 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 README
|
||||
* file for more details.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Written by Tuomas Lukka
|
||||
*/
|
||||
package org.gzigzag;
|
||||
import java.awt.*;
|
||||
|
||||
/** An integrated-circuit view. Currently we show only
|
||||
* dimensions.
|
||||
*/
|
||||
|
||||
public class ICView implements FlobView, ZOb {
|
||||
public static final String rcsid = "$Id: ICView.zob,v 1.3 2000/11/07 12:38:27 ajk Exp $";
|
||||
|
||||
public static boolean dbg = false;
|
||||
static final void p(String s) { if(dbg) System.out.println(s); }
|
||||
static final void pa(String s) { System.out.println(s); }
|
||||
|
||||
STRUCTPARAMS {
|
||||
}
|
||||
|
||||
public void raster(FlobSet into, FlobFactory fact, ZZCell view,
|
||||
String[]vds, ZZCell accursed) {
|
||||
Dimension d = into.getSize();
|
||||
|
||||
Dimension c = fact.getSize(null, 1);
|
||||
int cw = c.width;
|
||||
int ch = c.height;
|
||||
|
||||
ZZCell dimhead = ZZCursorReal.get(view.s("d.dims")).h("d.2");
|
||||
|
||||
fact.makeFlob(into, accursed, accursed, 1,
|
||||
(d.width-cw) / 2, 0, 1, cw, ch);
|
||||
int cury = ch+2;
|
||||
p("ic loop");
|
||||
for(ZZCell cur = dimhead; cur != null; ) {
|
||||
if(accursed.s(cur.t()) != null ||
|
||||
accursed.s(cur.t(),-1) != null) {
|
||||
fact.makeFlob(into, cur, cur, 1, (d.width-cw) / 2,
|
||||
cury, 1, cw, ch);
|
||||
cury += ch+2;
|
||||
}
|
||||
cur = cur.s("d.2");
|
||||
if(cur == dimhead) break;
|
||||
p("ic "+cur);
|
||||
}
|
||||
p("Out of ic");
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
// vim: set syntax=java :
|
||||
98
Java/flob/IdiosyncraticFlobFactory.zob
Normal file
98
Java/flob/IdiosyncraticFlobFactory.zob
Normal file
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
IdiosyncraticFlobFactory.zob
|
||||
*
|
||||
* Copyright (c) 2000, Ted Nelson and Tuomas Lukka
|
||||
*
|
||||
* You may use and distribute under the terms of either the GNU Lesser
|
||||
* General Public License, either version 2 of the license or,
|
||||
* at your choice, any later version. Alternatively, you may use and
|
||||
* distribute under the terms of the XPL.
|
||||
*
|
||||
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
|
||||
* the licenses.
|
||||
*
|
||||
* This software 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 README
|
||||
* file for more details.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Written by Tuomas Lukka
|
||||
*/
|
||||
|
||||
package org.gzigzag;
|
||||
import java.util.*;
|
||||
import java.awt.*;
|
||||
|
||||
/** A flob factory that shows each cell with its own view, if
|
||||
* desired.
|
||||
* The view should be connected negwards of the cell on
|
||||
* <code>d.cellview</code>, as a FlobFactory (CellView) ZOb.
|
||||
*/
|
||||
|
||||
public class IdiosyncraticFlobFactory implements FlobFactory, ZOb {
|
||||
public static final String rcsid = "$Id: IdiosyncraticFlobFactory.zob,v 1.5 2001/03/18 10:38:26 bfallenstein Exp $";
|
||||
public static boolean dbg = false;
|
||||
static final void p(String s) { if(dbg) System.out.println(s); }
|
||||
|
||||
STRUCTPARAMS {
|
||||
ZOb def
|
||||
= null;
|
||||
}
|
||||
|
||||
public FlobFactory getIdiosyncraticCellView(ZZCell c) {
|
||||
ZZCell h = c.getRootclone().h("d.cellview", true);
|
||||
if(h == null) return null;
|
||||
// XXX We *WILL* need a cache of ZObs...
|
||||
return (FlobFactory)ZZDefaultSpace.readZOb(h);
|
||||
}
|
||||
|
||||
/** Get the idiosyncratic or default cell view.
|
||||
* Never returns null.
|
||||
*/
|
||||
public FlobFactory getCellView(ZZCell c) {
|
||||
FlobFactory cv = getIdiosyncraticCellView(c);
|
||||
if(cv == null) cv = (FlobFactory)def;
|
||||
if(cv == null)
|
||||
throw new ZZError("No default view!");
|
||||
return cv;
|
||||
}
|
||||
|
||||
|
||||
public Dimension getSize(ZZCell c, float fract) {
|
||||
if(c == null)
|
||||
return ((FlobFactory)def).getSize(null, fract);
|
||||
return getCellView(c).getSize(c, fract);
|
||||
}
|
||||
|
||||
public Flob makeFlob(FlobSet into, ZZCell c, ZZCell handleCell,
|
||||
float fract,
|
||||
int x, int y, int d, int w, int h) {
|
||||
return getCellView(c).makeFlob(into, c, handleCell,
|
||||
fract, x, y, d, w, h);
|
||||
}
|
||||
public Flob placeFlob(FlobSet into, ZZCell c, ZZCell handleCell,
|
||||
float fract,
|
||||
int x, int y, int depth,
|
||||
float xfract, float yfract) {
|
||||
return getCellView(c).placeFlob(into, c, handleCell,
|
||||
fract, x, y, depth, xfract, yfract);
|
||||
}
|
||||
|
||||
public Flob centerFlob(FlobSet into, ZZCell c, ZZCell handleCell,
|
||||
float fract, Point p, int xalign, int yalign,
|
||||
int depth, Dimension d) {
|
||||
return getCellView(c).centerFlob(into, c, handleCell, fract, p,
|
||||
xalign, yalign, depth, d);
|
||||
}
|
||||
public Flob centerFlob(FlobSet into, ZZCell c, ZZCell handleCell,
|
||||
float fract, Point p, int xalign, int yalign, int depth) {
|
||||
return getCellView(c).centerFlob(into, c, handleCell, fract, p,
|
||||
xalign, yalign, depth);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// vim: set syntax=java :
|
||||
193
Java/flob/Level.java
Normal file
193
Java/flob/Level.java
Normal file
@@ -0,0 +1,193 @@
|
||||
/*
|
||||
Level.java
|
||||
*
|
||||
* Copyright (c) 2000, Ted Nelson and Tuomas Lukka
|
||||
*
|
||||
* You may use and distribute under the terms of either the GNU Lesser
|
||||
* General Public License, either version 2 of the license or,
|
||||
* at your choice, any later version. Alternatively, you may use and
|
||||
* distribute under the terms of the XPL.
|
||||
*
|
||||
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
|
||||
* the licenses.
|
||||
*
|
||||
* This software 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 README
|
||||
* file for more details.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Written by Benjamin Fallenstein
|
||||
*/
|
||||
|
||||
package org.gzigzag.module;
|
||||
import org.gzigzag.*;
|
||||
import java.awt.*;
|
||||
|
||||
/** Primitive actions for use with LevelRaster.
|
||||
* XXX join with LevelRaster?
|
||||
*/
|
||||
|
||||
public class Level {
|
||||
public static final String rcsid = "$Id: Level.java,v 1.6 2000/11/07 12:38:27 ajk Exp $";
|
||||
public static boolean dbg = false;
|
||||
static void p(String s) { if(dbg) System.out.println(s); }
|
||||
static void pa(String s) { System.out.println(s); }
|
||||
|
||||
// A "direction" in the ZZ space
|
||||
static class DimVector {
|
||||
String dim;
|
||||
int dir;
|
||||
DimVector rev; // The reverse vector
|
||||
|
||||
DimVector(String dim, int dir) {
|
||||
this.dim = dim; this.dir = dir; rev = new DimVector(this);
|
||||
}
|
||||
DimVector(DimVector rev) { dim=rev.dim; dir=-rev.dir; this.rev=rev; }
|
||||
|
||||
ZZCell get(ZZCell c) { return c.s(dim, dir); }
|
||||
ZZCell end(ZZCell c) { return c.h(dim, dir); }
|
||||
ZZCell end(ZZCell c, boolean ensuremove) {
|
||||
return c.h(dim, dir, ensuremove);
|
||||
}
|
||||
ZZCell create(ZZCell c) { return c.N(dim, dir); }
|
||||
ZZCell[] rank(ZZCell c, boolean includeThis) {
|
||||
return c.readRank(dim, dir, includeThis);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** A set of dimension vectors: linkdim, targetdim and tunneldim.
|
||||
*/
|
||||
static class DimSet {
|
||||
DimVector linkdim;
|
||||
DimVector targetdim;
|
||||
DimVector tunneldim;
|
||||
DimSet rev;
|
||||
|
||||
DimSet(String dims[]) {
|
||||
linkdim = new DimVector(dims[0], 1);
|
||||
targetdim = new DimVector(dims[1], 1);
|
||||
tunneldim = new DimVector(dims[2], 1);
|
||||
rev = new DimSet(this);
|
||||
}
|
||||
|
||||
DimSet(DimSet rev) {
|
||||
linkdim = rev.targetdim.rev;
|
||||
targetdim = rev.linkdim.rev;
|
||||
tunneldim = rev.tunneldim.rev;
|
||||
this.rev = rev;
|
||||
}
|
||||
|
||||
DimSet(ZZCell viewc) {
|
||||
ZZCell[] dimcurs = viewc.readRank("d.dims", 1, false);
|
||||
linkdim = new DimVector(
|
||||
ZZCursorReal.get(dimcurs[0]).getText(), 1);
|
||||
targetdim = new DimVector(
|
||||
ZZCursorReal.get(dimcurs[1]).getText(), 1);
|
||||
tunneldim = new DimVector(
|
||||
ZZCursorReal.get(dimcurs[2]).getText(), 1);
|
||||
rev = new DimSet(this);
|
||||
}
|
||||
|
||||
boolean islink(ZZCell c) {
|
||||
return targetdim.get(c) != null || rev.targetdim.get(c) != null;
|
||||
}
|
||||
}
|
||||
|
||||
static class Performer {
|
||||
ZZCell viewc, c;
|
||||
DimSet ds;
|
||||
boolean lnk;
|
||||
String act;
|
||||
|
||||
Performer(ZZCell viewc) {
|
||||
this.viewc = viewc; c = ZZCursorReal.get(viewc);
|
||||
ds = new DimSet(viewc);
|
||||
lnk = ds.islink(c);
|
||||
// XXX why doesn't this work:
|
||||
// act = ZZDefaultSpace.getDirActionWaitingAndClear(viewc);
|
||||
ZZCell nac = ZZDefaultSpace
|
||||
.findOnClientlist(c.getSpace(), "NextAction", true);
|
||||
nac = nac.getOrNewCell("d.1", 1, null);
|
||||
act = nac.getText();
|
||||
nac.setText("");
|
||||
}
|
||||
|
||||
public void perf(ZZCell to, DimVector dim) { perf(to, dim, c); }
|
||||
|
||||
public void perf(ZZCell to, DimVector dim, ZZCell from) {
|
||||
// XXX Extend to HOP and NEW!
|
||||
// HOP just uses dim; NEW needs to check if link AFTER INSERT
|
||||
if(act.equals(""))
|
||||
ZZCursorReal.set(viewc, to);
|
||||
else if(act.equals("HOP")) {
|
||||
if(!lnk || dim == null) return;
|
||||
to.insert(dim.dim, dim.dir, from);
|
||||
} else if(act.equals("NEW")) {
|
||||
if(dim == null) return;
|
||||
ZZCell nc = dim.create(from);
|
||||
if(ds.islink(nc)) {
|
||||
if(ds.targetdim.get(nc) == null) ds.targetdim.create(nc);
|
||||
else ds.rev.targetdim.create(nc);
|
||||
}
|
||||
} else
|
||||
System.out.println("Level module can't do "+act);
|
||||
}
|
||||
|
||||
public void dir(int d, int b) {
|
||||
DimSet ds = d < 0 ? this.ds.rev : this.ds;
|
||||
ZZCell to;
|
||||
if(lnk) {
|
||||
if(b == 0) { perf(ds.targetdim.end(c), null); return; }
|
||||
else if(b < 0) {
|
||||
to = ds.targetdim.get(c);
|
||||
if(to != null && ds.targetdim.get(to) != null)
|
||||
perf(to, ds.targetdim);
|
||||
} else {
|
||||
to = ds.targetdim.rev.get(c);
|
||||
if(to != null) perf(to, ds.targetdim.rev);
|
||||
}
|
||||
} else {
|
||||
if(b < 0) {
|
||||
perf(ds.linkdim.get(c), ds.linkdim);
|
||||
} else if(b == 0) {
|
||||
to = ds.tunneldim.get(c);
|
||||
ZZCell[] rnk = ds.linkdim.rank(c, false);
|
||||
if(to == null && rnk.length > 0)
|
||||
to = rnk[rnk.length / 2];
|
||||
perf(to, ds.tunneldim);
|
||||
} else {
|
||||
to = ds.linkdim.end(c);
|
||||
perf(to, ds.linkdim, to);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static public ZZModule module = new ZZModule() {
|
||||
public void action(String id,
|
||||
ZZCell code,
|
||||
ZZCell target,
|
||||
ZZView view, ZZView cview, String key, Point pt, ZZScene xi) {
|
||||
|
||||
Performer p = new Performer(view.getViewcell());
|
||||
|
||||
if(id.equals("UpLeft")) p.dir(-1, -1);
|
||||
else if(id.equals("Up")) p.dir(-1, 0);
|
||||
else if(id.equals("UpRight")) p.dir(-1, 1);
|
||||
else if(id.equals("DownLeft")) p.dir(1, -1);
|
||||
else if(id.equals("Down")) p.dir(1, 0);
|
||||
else if(id.equals("DownRight")) p.dir(1, 1);
|
||||
else System.out.println("Level module: Unknown code '"+id+"'");
|
||||
}
|
||||
|
||||
public ZOb newZOb(String id) {
|
||||
if(id.equals("Raster")) return new LevelView();
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
492
Java/flob/LevelView.zob
Normal file
492
Java/flob/LevelView.zob
Normal file
@@ -0,0 +1,492 @@
|
||||
/*
|
||||
LevelRaster.zob
|
||||
*
|
||||
* Copyright (c) 2000, Ted Nelson and Tuomas Lukka
|
||||
*
|
||||
* You may use and distribute under the terms of either the GNU Lesser
|
||||
* General Public License, either version 2 of the license or,
|
||||
* at your choice, any later version. Alternatively, you may use and
|
||||
* distribute under the terms of the XPL.
|
||||
*
|
||||
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
|
||||
* the licenses.
|
||||
*
|
||||
* This software 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 README
|
||||
* file for more details.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Written by Benjamin Fallenstein
|
||||
*/
|
||||
|
||||
package org.gzigzag;
|
||||
import java.awt.*;
|
||||
import java.util.*;
|
||||
|
||||
/** A raster for multiple-level structures.
|
||||
* Interprets two dimensions as many-to-many relationship. Also interprets
|
||||
* third dimension as one-to-one relationships which are shown the same way
|
||||
* as the many-to-many relationships. For many-to-many relationships with
|
||||
* link cells, shows the link cells.
|
||||
*/
|
||||
|
||||
/* Some XXX'es:
|
||||
- fix the damn occupiedbreadth bug!!!
|
||||
- should move the parentlinks in the right place
|
||||
- primitive actions for leveled visualization (including move)
|
||||
- loose linking so that new links can be created? or: new link creates
|
||||
new target, too? or maybe: in loose mode, links w/o target are shown as
|
||||
that, links w/o target? yeah, way to go. (anyways, should new link also
|
||||
create new target or not? pbly yes, eh?)
|
||||
- gaps that shrink; think depthwise gapping through again
|
||||
*/
|
||||
|
||||
public class LevelView implements FlobView, ZOb {
|
||||
public static final String rcsid = "$Id$";
|
||||
public static boolean dbg = false ;
|
||||
static final void p(String s) { if(dbg) System.out.println(s); }
|
||||
static final void pa(String s) { System.out.println(s); }
|
||||
|
||||
STRUCTPARAMS {
|
||||
/** The size factor applied to cells. */
|
||||
float initmul
|
||||
= (float)1.6;
|
||||
|
||||
/** How many recursion levels shall we render (on both sides of the
|
||||
* root)? */
|
||||
int maxdepth
|
||||
= 4;
|
||||
|
||||
/** The breadth distance between neigbouring cells. */
|
||||
int bgap
|
||||
= 15;
|
||||
|
||||
/** The depth distance between a cell and a link */
|
||||
int dgap
|
||||
= 10;
|
||||
|
||||
/** The factor of enlargement of cells as they move away
|
||||
depthwise from the accursed cell. Element 0 is
|
||||
horizontal, element 1 is vertical. */
|
||||
float shrink
|
||||
= (float)0.7;
|
||||
|
||||
/** The enlargement factor applied to link cells. Think linkshrink! */
|
||||
float linkshrink
|
||||
= (float)0.25;
|
||||
|
||||
/** Should the tree be shown "depthhorizontal", ie. depth rightwards? */
|
||||
boolean depthhorizontal
|
||||
= false;
|
||||
|
||||
/** Should the headcell be used on both dimensions?
|
||||
* Normally on target dim, tailcell is used. */
|
||||
boolean bothhead
|
||||
= false;
|
||||
|
||||
/** Are links without targets interpreted as targets?
|
||||
* If two elements are given, the first is used for upstream- and the
|
||||
* second for downstream connections. */
|
||||
boolean[] loose // 1..2
|
||||
= new boolean[] { false, false };
|
||||
}
|
||||
|
||||
INITIALIZE {
|
||||
if(loose.length == 1)
|
||||
loose = new boolean[] { loose[0], loose[0] };
|
||||
}
|
||||
|
||||
DimVector[] dims;
|
||||
Coordinates treegap; // gap converted to a Coordinates instance
|
||||
Coordinates linkgap; // same with linkshrink applied
|
||||
Coordinates[] cellsizes;
|
||||
boolean looseup, loosedown; // XXX ???
|
||||
|
||||
|
||||
// A "direction" in the ZZ space
|
||||
static class DimVector {
|
||||
String dim;
|
||||
int dir;
|
||||
DimVector rev; // The reverse vector
|
||||
|
||||
DimVector(String dim, int dir) {
|
||||
this.dim = dim; this.dir = dir; rev = new DimVector(this);
|
||||
}
|
||||
DimVector(DimVector rev) { dim=rev.dim; dir=-rev.dir; this.rev=rev; }
|
||||
|
||||
ZZCell get(ZZCell c) { return c.s(dim, dir); }
|
||||
ZZCell end(ZZCell c) { return c.h(dim, dir); }
|
||||
ZZCell end(ZZCell c, boolean ensuremove) {
|
||||
return c.h(dim, dir, ensuremove);
|
||||
}
|
||||
ZZCell[] rank(ZZCell c, boolean includeThis) {
|
||||
return c.readRank(dim, dir, includeThis);
|
||||
}
|
||||
}
|
||||
|
||||
class Coordinates {
|
||||
public int breadth;
|
||||
public int depth;
|
||||
|
||||
public int x() { return depthhorizontal ? depth : breadth; }
|
||||
public int y() { return depthhorizontal ? breadth : depth; }
|
||||
|
||||
public void set(int setx, int sety) {
|
||||
if(depthhorizontal) {
|
||||
depth = setx; breadth = sety;
|
||||
} else {
|
||||
breadth = setx; depth = sety;
|
||||
}
|
||||
}
|
||||
|
||||
Coordinates(Dimension d) { set(d.width, d.height); }
|
||||
Coordinates(int b, int d) { breadth = b; depth = d; }
|
||||
Coordinates(int i, int j, boolean treecoords) {
|
||||
if(treecoords) { breadth = i; depth = j; }
|
||||
else set(i, j);
|
||||
}
|
||||
Coordinates(Coordinates c, float fract) {
|
||||
breadth = (int) (c.breadth * fract);
|
||||
depth = (int) (c.depth * fract);
|
||||
}
|
||||
}
|
||||
|
||||
DimVector[] directeddims(boolean upwards) {
|
||||
return new DimVector[] {
|
||||
upwards ? dims[1].rev : dims[0],
|
||||
upwards ? dims[0].rev : dims[1],
|
||||
upwards ? dims[2].rev : dims[2]
|
||||
};
|
||||
}
|
||||
|
||||
// STEP 1: Tree generation. This may be overridden
|
||||
// Note that "children" are cells away from root, and "parents" are
|
||||
// cells towards root. Only the links to the parents are drawn.
|
||||
CellInfo connectCell(ZZCell c, ZZCell linkc, ZZCell parentc,
|
||||
int steps, boolean upwards) {
|
||||
CellInfo r = new CellInfo(c, linkc, parentc, steps, upwards);
|
||||
boolean more = steps < maxdepth - 1;
|
||||
|
||||
DimVector[] ds = directeddims(upwards);
|
||||
DimVector linkdim = ds[0];
|
||||
DimVector targetdim = ds[1];
|
||||
DimVector tunneldim = ds[2];
|
||||
|
||||
ZZCell target, parent;
|
||||
if((target=tunneldim.get(c)) != null && more)
|
||||
r.childinfo.addElement(connectCell(target, null, c,
|
||||
steps+1, upwards));
|
||||
if((parent=tunneldim.rev.get(c)) != null)
|
||||
r.parentlinks.addElement(parent);
|
||||
|
||||
ZZCell[] links = linkdim.rank(c, true);
|
||||
for(int i=0; more && i<links.length; i++) {
|
||||
target = targetdim.end(links[i], !loose[upwards ? 0 : 1]);
|
||||
if(target == null) continue;
|
||||
if(target == links[i])
|
||||
r.childinfo.addElement(connectCell(target, null, c,
|
||||
steps+1, upwards));
|
||||
else
|
||||
r.childinfo.addElement(connectCell(target, links[i], c,
|
||||
steps+1, upwards));
|
||||
}
|
||||
|
||||
if((parent=linkdim.rev.end(c)) != null && parent != c)
|
||||
r.parentlinks.addElement(parent);
|
||||
|
||||
ZZCell[] parentlinks = targetdim.rev.rank(c, false);
|
||||
for(int i=0; i<parentlinks.length; i++)
|
||||
if(loose[upwards?1:0] || linkdim.rev.get(parentlinks[i]) != null)
|
||||
r.parentlinks.addElement(parentlinks[i]);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
class CellInfo {
|
||||
// Stuff set in step 1 (tree generation)
|
||||
ZZCell c, linkc, parentc; // Linkcell CAN be null
|
||||
Vector childinfo = new Vector();
|
||||
Vector parentlinks = new Vector(); // can include linkless parents
|
||||
int steps; // from root
|
||||
boolean upwards;
|
||||
|
||||
// Stuff set in step 2 (size & breadth computing)
|
||||
Coordinates size;
|
||||
int occupiedbreadth = 0;
|
||||
|
||||
CellInfo(ZZCell c, ZZCell linkc, ZZCell parentc, int steps,
|
||||
boolean upwards) {
|
||||
this.c = c; this.linkc = linkc; this.parentc = parentc;
|
||||
this.steps = steps; this.upwards = upwards;
|
||||
}
|
||||
|
||||
// STEP 2: Compute the size of cell and breadth of tree part
|
||||
public int computesize() {
|
||||
size = cellsizes[steps];
|
||||
for(Enumeration e = childinfo.elements(); e.hasMoreElements();)
|
||||
occupiedbreadth += ((CellInfo) e.nextElement()).computesize()
|
||||
+ treegap.breadth;
|
||||
if(occupiedbreadth < size.breadth)
|
||||
occupiedbreadth = size.breadth;
|
||||
return occupiedbreadth;
|
||||
}
|
||||
|
||||
// STEP 3: Put the cell and its parentlinks into a continuum
|
||||
public void putall(Continuum co, int bstart, int dstart) {
|
||||
int bcoord=bstart, dcoord=dstart;
|
||||
if(upwards) dcoord -= size.depth;
|
||||
Coordinates pos = new Coordinates(
|
||||
bcoord + occupiedbreadth/2 - size.breadth/2,
|
||||
dcoord);
|
||||
boolean newlypositioned = co.put(c, pos, size, steps, false);
|
||||
if(parentc != null) {
|
||||
if(upwards) co.putlink(c, linkc, parentc);
|
||||
else co.putlink(parentc, linkc, c);
|
||||
}
|
||||
|
||||
if(!newlypositioned && parentc != null) return;
|
||||
|
||||
int childdcoord = dcoord + treegap.depth * (upwards ? -1 : 1);
|
||||
if(!upwards) childdcoord += size.depth;
|
||||
bcoord += treegap.breadth / 2;
|
||||
for(Enumeration e = childinfo.elements(); e.hasMoreElements();) {
|
||||
CellInfo ci = (CellInfo)e.nextElement();
|
||||
ci.putall(co, bcoord, childdcoord);
|
||||
bcoord += ci.occupiedbreadth + treegap.breadth;
|
||||
}
|
||||
|
||||
if(parentc == null) return;
|
||||
|
||||
int bmiddle = pos.breadth + size.breadth/2;
|
||||
Coordinates linksize = new Coordinates(size, linkshrink);
|
||||
int plnkbreadth = linkgap.breadth + linksize.breadth;
|
||||
bcoord = bmiddle - (int)(plnkbreadth * parentlinks.size() / 2);
|
||||
bcoord += linkgap.breadth / 2;
|
||||
dcoord += linkgap.depth * (upwards ? 1 : -2);
|
||||
dcoord += size.depth * (upwards ? 1 : 0);
|
||||
|
||||
for(Enumeration e = parentlinks.elements(); e.hasMoreElements();) {
|
||||
Coordinates lpos = new Coordinates(bcoord, dcoord);
|
||||
ZZCell plinkc = (ZZCell)e.nextElement();
|
||||
if(co.put(plinkc, lpos, linksize, steps, true))
|
||||
co.putsmalllink(c, plinkc, upwards);
|
||||
bcoord += linksize.breadth + linkgap.breadth;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Continuum {
|
||||
class Link { ZZCell fromc, linkc, toc; }
|
||||
|
||||
// Information used for rastering
|
||||
Hashtable posns = new Hashtable(); // POSitionNS
|
||||
Hashtable sizes = new Hashtable();
|
||||
Hashtable depths = new Hashtable();
|
||||
Vector links = new Vector();
|
||||
Hashtable linksmalls = new Hashtable();
|
||||
|
||||
// Information used only while generating the continuum
|
||||
Hashtable smalls = new Hashtable();
|
||||
Hashtable linkbigs = new Hashtable();
|
||||
|
||||
Coordinates getpos(ZZCell c) { return (Coordinates)posns.get(c); }
|
||||
Coordinates getsize(ZZCell c) { return (Coordinates)sizes.get(c); }
|
||||
int getdepth(ZZCell c) { return ((Integer)depths.get(c)).intValue(); }
|
||||
|
||||
// Return false if the cell has already been positioned
|
||||
public boolean put(ZZCell c, Coordinates pos, Coordinates size,
|
||||
int steps, boolean small) {
|
||||
if(posns.containsKey(c) && (small || !smalls.containsKey(c)))
|
||||
return false;
|
||||
posns.put(c, pos);
|
||||
sizes.put(c, size);
|
||||
depths.put(c, new Integer(steps+1));
|
||||
if(small) smalls.put(c, c);
|
||||
return true;
|
||||
}
|
||||
|
||||
public void putsmalllink(ZZCell fromc, ZZCell linkc, boolean up) {
|
||||
if(linkbigs.containsKey(linkc)) return;
|
||||
Link link = new Link(); link.linkc = linkc;
|
||||
if(up) { link.fromc = fromc; link.toc = linkc; }
|
||||
else { link.fromc = linkc; link.toc = fromc; }
|
||||
linksmalls.put(linkc, link);
|
||||
}
|
||||
|
||||
public void putlink(ZZCell fromc, ZZCell linkc, ZZCell toc) {
|
||||
Link link = new Link();
|
||||
link.fromc = fromc; link.linkc = linkc; link.toc = toc;
|
||||
links.addElement(link);
|
||||
if(linkc != null && linksmalls.containsKey(linkc))
|
||||
linksmalls.remove(linkc);
|
||||
if(linkc != null) linkbigs.put(linkc, link);
|
||||
}
|
||||
|
||||
// STEP 4: Position link cells
|
||||
public void positionlinkcells() {
|
||||
for(Enumeration e = links.elements(); e.hasMoreElements();) {
|
||||
Link link = (Link)e.nextElement();
|
||||
|
||||
if(link.linkc == null) continue; // only draw a line
|
||||
|
||||
int fdepth = getdepth(link.fromc);
|
||||
int tdepth = getdepth(link.toc);
|
||||
int depth = fdepth > tdepth ? fdepth : tdepth;
|
||||
Coordinates size = new Coordinates(cellsizes[depth-1],
|
||||
linkshrink);
|
||||
Coordinates fpos = getpos(link.fromc);
|
||||
Coordinates fsize = getsize(link.fromc);
|
||||
Coordinates tpos = getpos(link.toc);
|
||||
Coordinates tsize = getsize(link.toc);
|
||||
Coordinates pos = new Coordinates(
|
||||
(fpos.breadth + (fsize.breadth/2) +
|
||||
tpos.breadth + (tsize.breadth/2) - size.breadth) / 2,
|
||||
(fpos.depth + fsize.depth + tpos.depth - size.depth) / 2);
|
||||
boolean succ = put(link.linkc, pos, size, depth, false);
|
||||
p((succ ? "S" : "Uns")+"uccessfully positioned link cell: "+
|
||||
link.linkc.getText());
|
||||
}
|
||||
}
|
||||
|
||||
// STEP 5: Raster the continuum into a flob set
|
||||
public void raster(FlobSet into, FlobFactory fact, ZZCell view) {
|
||||
for(Enumeration e = posns.keys(); e.hasMoreElements();) {
|
||||
ZZCell c = (ZZCell)e.nextElement();
|
||||
Coordinates pos = getpos(c);
|
||||
Coordinates size = getsize(c);
|
||||
int depth = getdepth(c);
|
||||
fact.makeFlob(into, c, c, 1, pos.x(), pos.y(), depth,
|
||||
size.x(), size.y());
|
||||
}
|
||||
for(Enumeration e = linksmalls.elements(); e.hasMoreElements();) {
|
||||
Link link = (Link)e.nextElement();
|
||||
putlink(link.fromc, null, link.toc);
|
||||
}
|
||||
for(Enumeration e = links.elements(); e.hasMoreElements();) {
|
||||
Link link = (Link)e.nextElement();
|
||||
int fdepth = getdepth(link.fromc);
|
||||
int tdepth = getdepth(link.toc);
|
||||
int depth = fdepth > tdepth ? fdepth : tdepth;
|
||||
Coordinates fpos = getpos(link.fromc);
|
||||
Coordinates fsize = getsize(link.fromc);
|
||||
Coordinates tpos = getpos(link.toc);
|
||||
Coordinates tsize = getsize(link.toc);
|
||||
|
||||
Coordinates from = new Coordinates(
|
||||
fpos.breadth + fsize.breadth/2, fpos.depth + fsize.depth);
|
||||
Coordinates to = new Coordinates(
|
||||
tpos.breadth + tsize.breadth/2, tpos.depth);
|
||||
|
||||
into.add(new LineDecor(from.x(), from.y(), to.x(), to.y(),
|
||||
Color.red, depth));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void initdims(String[] dims) {
|
||||
this.dims = new DimVector[] {
|
||||
new DimVector(dims[0], 1),
|
||||
new DimVector(dims[1], bothhead ? -1 : 1),
|
||||
new DimVector(dims[2], 1),
|
||||
};
|
||||
}
|
||||
|
||||
public ZZCell look(ZZCell c, int x, int y) {
|
||||
Coordinates co = new Coordinates(x, y, false);
|
||||
DimVector d=null, t=null;
|
||||
if(co.depth == 0)
|
||||
return null;
|
||||
else if(co.depth < 0) {
|
||||
d = dims[0];
|
||||
t = dims[3];
|
||||
} else {
|
||||
d = dims[1].rev;
|
||||
t = dims[3].rev;
|
||||
}
|
||||
|
||||
if(co.breadth < 0)
|
||||
return d.get(c);
|
||||
else if(co.breadth > 0)
|
||||
return d.end(c, true);
|
||||
else {
|
||||
if(t.get(c) != null) return t.get(c);
|
||||
ZZCell[] rank = d.rank(c, false);
|
||||
if(rank.length == 0) return null;
|
||||
return rank[rank.length / 2];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void raster(FlobSet into, FlobFactory fact,
|
||||
ZZCell view, String[] dims, ZZCell c) {
|
||||
Dimension cs = fact.getSize(null, initmul);
|
||||
cellsizes = new Coordinates[maxdepth];
|
||||
cellsizes[0] = new Coordinates(cs);
|
||||
for(int i=1; i<maxdepth; i++)
|
||||
cellsizes[i] = new Coordinates(cellsizes[i-1], shrink);
|
||||
treegap = new Coordinates(bgap, cellsizes[0].depth + dgap*4);
|
||||
linkgap = new Coordinates(bgap/4, dgap);
|
||||
|
||||
Coordinates fs = new Coordinates(into.getSize());
|
||||
p("Prepared canvas size");
|
||||
|
||||
initdims(dims);
|
||||
DimVector linkdim = this.dims[0], targetdim = this.dims[1],
|
||||
tunneldim = this.dims[2];
|
||||
p("Prepared DimVectors");
|
||||
|
||||
CellInfo uproot, downroot;
|
||||
boolean islink;
|
||||
|
||||
// CALL 1: Tree generation. This may be overridden
|
||||
p("Starting LevelRaster call one");
|
||||
|
||||
if(linkdim.rev.get(c) != null && targetdim.get(c) != null) {
|
||||
islink = true;
|
||||
uproot = connectCell(linkdim.rev.end(c), null, c, 1, true);
|
||||
downroot = connectCell(targetdim.end(c), null, c, 1, false);
|
||||
} else {
|
||||
islink = false;
|
||||
uproot = connectCell(c, null, null, 0, true);
|
||||
downroot = connectCell(c, null, null, 0, false);
|
||||
}
|
||||
|
||||
// CALL 2: Compute the size of cell and breadth of tree part
|
||||
p("Starting LevelRaster call two");
|
||||
|
||||
uproot.computesize(); downroot.computesize();
|
||||
|
||||
// CALL 3: Put the cell and its parentlinks into a continuum
|
||||
p("Starting LevelRaster call three");
|
||||
|
||||
Continuum co = new Continuum();
|
||||
int upbstart = (fs.breadth - uproot.occupiedbreadth) / 2;
|
||||
int downbstart = (fs.breadth - downroot.occupiedbreadth) / 2;
|
||||
int updstart = (fs.depth + cellsizes[0].depth) / 2;
|
||||
int downdstart = (fs.depth - cellsizes[0].depth) / 2;
|
||||
if(islink) {
|
||||
co.put(c, new Coordinates((fs.breadth - cellsizes[0].breadth) / 2,
|
||||
downdstart), cellsizes[0],
|
||||
0, false);
|
||||
updstart -= treegap.depth/4*3; //+ cellsizes[0].depth;
|
||||
downdstart += treegap.depth/4*3;
|
||||
}
|
||||
downroot.putall(co, downbstart, downdstart);
|
||||
uproot.putall(co, upbstart, updstart);
|
||||
|
||||
// CALL 4: Position link cells
|
||||
p("Starting LevelRaster call four");
|
||||
|
||||
co.positionlinkcells();
|
||||
|
||||
// CALL 5: Raster the continuum into a flob set
|
||||
p("Starting LevelRaster call five");
|
||||
|
||||
co.raster(into, fact, view);
|
||||
}
|
||||
}
|
||||
|
||||
// vim: set syntax=java :
|
||||
101
Java/flob/LineDecor.java
Normal file
101
Java/flob/LineDecor.java
Normal file
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
LineDecor.java
|
||||
*
|
||||
* Copyright (c) 2000, Ted Nelson and Tuomas Lukka
|
||||
*
|
||||
* You may use and distribute under the terms of either the GNU Lesser
|
||||
* General Public License, either version 2 of the license or,
|
||||
* at your choice, any later version. Alternatively, you may use and
|
||||
* distribute under the terms of the XPL.
|
||||
*
|
||||
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
|
||||
* the licenses.
|
||||
*
|
||||
* This software 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 README
|
||||
* file for more details.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Written by Tuomas Lukka
|
||||
*/
|
||||
|
||||
package org.gzigzag;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.util.*;
|
||||
|
||||
public class LineDecor extends CoordDecor {
|
||||
public static final String rcsid = "$Id: LineDecor.java,v 1.9 2000/10/26 18:15:58 tjl Exp $";
|
||||
public static boolean dbg = false;
|
||||
static final void p(String s) { if(dbg) System.out.println(s); }
|
||||
static final void pa(String s) { System.out.println(s); }
|
||||
|
||||
Color color;
|
||||
|
||||
/** A simple class that knows how to efficiently build
|
||||
* these things.
|
||||
*/
|
||||
static public class Builder extends CoordDecor.Builder {
|
||||
Color col;
|
||||
public Builder(FlobSet into, Color col) {
|
||||
super(into);
|
||||
this.col = col;
|
||||
}
|
||||
/** Make a line.
|
||||
*/
|
||||
public final void l(int x0, int y0, int x1, int y1) {
|
||||
makeRoom(4);
|
||||
p[curp] = x0;
|
||||
p[curp+1] = y0;
|
||||
p[curp+2] = x1;
|
||||
p[curp+3] = y1;
|
||||
curp += 4;
|
||||
}
|
||||
protected Renderable create() {
|
||||
p("Create linedecor "+p+" "+curp+" "+col+" "+d);
|
||||
return new LineDecor(p, curp, col, d);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public LineDecor(int[] coords, int n, int d) {
|
||||
this(coords, n, null, d);
|
||||
}
|
||||
|
||||
/** Usual constructor.
|
||||
* @param coords The coordinates for the lines, given as
|
||||
* quadruplets x1, y1, x2, y2.
|
||||
*/
|
||||
public LineDecor(int[] coords, int n, Color color, int d) {
|
||||
super(coords, n, d);
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
public LineDecor(int x1, int y1, int x2, int y2, Color color, int d) {
|
||||
super(null, 4, d);
|
||||
this.coords = new int[] {
|
||||
x1, y1, x2, y2
|
||||
};
|
||||
this.color = color;
|
||||
this.d = d;
|
||||
}
|
||||
|
||||
public void render(Graphics g) {
|
||||
Color old = null;
|
||||
if(color != null) {
|
||||
old = g.getColor();
|
||||
g.setColor(color);
|
||||
}
|
||||
|
||||
for(int i=0; i+3<n; i+=4) {
|
||||
g.drawLine(coords[i], coords[i+1],
|
||||
coords[i+2], coords[i+3]);
|
||||
}
|
||||
|
||||
if(old != null)
|
||||
g.setColor(old);
|
||||
}
|
||||
|
||||
}
|
||||
112
Java/flob/MagGrid.zob
Normal file
112
Java/flob/MagGrid.zob
Normal file
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
MagGrid.java
|
||||
*
|
||||
* Copyright (c) 2000, Ted Nelson and Tuomas Lukka
|
||||
*
|
||||
* You may use and distribute under the terms of either the GNU Lesser
|
||||
* General Public License, either version 2 of the license or,
|
||||
* at your choice, any later version. Alternatively, you may use and
|
||||
* distribute under the terms of the XPL.
|
||||
*
|
||||
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
|
||||
* the licenses.
|
||||
*
|
||||
* This software 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 README
|
||||
* file for more details.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Written by Tuomas Lukka
|
||||
*/
|
||||
package org.gzigzag;
|
||||
import java.awt.*;
|
||||
|
||||
/** A grid magnified from the center.
|
||||
*/
|
||||
|
||||
public class MagGrid extends GridGeom implements ZOb {
|
||||
public static final String rcsid = "$Id: MagGrid.zob,v 1.2.10.1 2001/08/24 19:58:24 bfallenstein Exp $";
|
||||
|
||||
STRUCTPARAMS {
|
||||
float[] shrink // 2..2
|
||||
= new float[] {(float)1, (float)1};
|
||||
float[] initmul // 2..2
|
||||
= new float[] {(float)1.4, (float)1.55};
|
||||
int[] gap // 2..2
|
||||
= new int[] {6, 6};
|
||||
/** Whether to fit all cells into view or leave
|
||||
* edges hanging outside.
|
||||
*/
|
||||
boolean fit
|
||||
= false;
|
||||
}
|
||||
|
||||
int[] xs;
|
||||
int[] ys;
|
||||
public Dimension setSizes(Dimension normalcell, Dimension canvas) {
|
||||
Dimension ret = new Dimension();
|
||||
ret.width = 1;
|
||||
int cur = (int)(normalcell.width * initmul[0]);
|
||||
int xw;
|
||||
for(xw = cur; xw <= canvas.width && cur > 1; xw += 2*cur+2*gap[0]) {
|
||||
ret.width +=2;
|
||||
cur = (int)(cur * shrink[0]);
|
||||
}
|
||||
if(fit) {
|
||||
xw -= 2*cur+2*gap[0];
|
||||
ret.width -= 2;
|
||||
}
|
||||
|
||||
xs = new int[ret.width + 1];
|
||||
cur = (int)(normalcell.width * initmul[0]);
|
||||
xs[ret.width / 2] = cur;
|
||||
for(int i=1; i<ret.width/2+1; i++) {
|
||||
cur = (int)(cur * shrink[0]);
|
||||
xs[ret.width/2-i] = xs[ret.width/2+i] = cur;
|
||||
}
|
||||
cur = (canvas.width - xw)/2;
|
||||
for(int i=0; i<xs.length; i++) {
|
||||
int l = xs[i];
|
||||
xs[i] = cur;
|
||||
cur += l;
|
||||
}
|
||||
|
||||
cur = (int)(normalcell.height * initmul[1]);
|
||||
int yw;
|
||||
for(yw = cur; yw <= canvas.height && cur > 1; yw += 2*cur+2*gap[1]) {
|
||||
ret.height +=2;
|
||||
cur = (int)(cur * shrink[1]);
|
||||
}
|
||||
if(fit) {
|
||||
yw -= 2*cur+2*gap[1];
|
||||
ret.height -= 2;
|
||||
}
|
||||
|
||||
ys = new int[ret.height + 1];
|
||||
cur = (int)(normalcell.height * initmul[1]);
|
||||
ys[ret.height / 2] = cur;
|
||||
for(int i=1; i<ret.height/2+1; i++) {
|
||||
cur = (int)(cur * shrink[1]);
|
||||
ys[ret.height/2-i] = ys[ret.height/2+i] = cur;
|
||||
}
|
||||
cur = (canvas.height - yw)/2;
|
||||
for(int i=0; i<ys.length; i++) {
|
||||
int l = ys[i];
|
||||
ys[i] = cur;
|
||||
cur += l;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
public Rectangle getCell(int x, int y, Rectangle rect) {
|
||||
rect.x = xs[x];
|
||||
rect.y = ys[y];
|
||||
rect.width = xs[x+1]-xs[x] - gap[0];
|
||||
rect.height = ys[y+1]-ys[y] - gap[1];
|
||||
return rect;
|
||||
}
|
||||
}
|
||||
|
||||
// vim: set syntax=java :
|
||||
|
||||
282
Java/flob/ManyToManyView.zob
Normal file
282
Java/flob/ManyToManyView.zob
Normal file
@@ -0,0 +1,282 @@
|
||||
/*
|
||||
ManyToManyRaster.zob
|
||||
*
|
||||
* Copyright (c) 2000, Ted Nelson and Tuomas Lukka
|
||||
*
|
||||
* You may use and distribute under the terms of either the GNU Lesser
|
||||
* General Public License, either version 2 of the license or,
|
||||
* at your choice, any later version. Alternatively, you may use and
|
||||
* distribute under the terms of the XPL.
|
||||
*
|
||||
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
|
||||
* the licenses.
|
||||
*
|
||||
* This software 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 README
|
||||
* file for more details.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Written by Tuomas Lukka and Tuukka Hastrup
|
||||
*/
|
||||
|
||||
|
||||
package org.gzigzag;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.util.*;
|
||||
|
||||
public class ManyToManyView implements FlobView, ZOb {
|
||||
public static final String rcsid = "$Id$";
|
||||
public static final boolean dbg = false;
|
||||
static final void p(String s) { if(dbg) System.out.println(s); }
|
||||
static final void pa(String s) { System.out.println(s); }
|
||||
|
||||
// Following are the parameters out of which the constructor
|
||||
// is created.
|
||||
|
||||
STRUCTPARAMS {
|
||||
|
||||
/** The factor to shrink the cells with when moving away from
|
||||
* center.
|
||||
*/
|
||||
float[] shrink // 2..2
|
||||
= new float[] {(float)0.75, (float)0.95};
|
||||
|
||||
/** The factor the center cell is enlarged with from default.
|
||||
*/
|
||||
float initmul
|
||||
= (float)1.0;
|
||||
|
||||
/** The distance between neighbouring cells.
|
||||
*/
|
||||
int[] gap // 2..2
|
||||
= new int[] {0, 0};
|
||||
|
||||
}
|
||||
|
||||
public void raster(FlobSet into, FlobFactory fact,
|
||||
ZZCell view, String[] dims, ZZCell accursed) {
|
||||
|
||||
Dimension fs = into.getSize();
|
||||
Dimension maxsz = fact.getSize(null, initmul);
|
||||
|
||||
// Calculate number of X and Y divisions.
|
||||
// There are two of each cell size. Go on until that is
|
||||
// too much.
|
||||
|
||||
int nx = 0;
|
||||
float curl = maxsz.width;
|
||||
for(int xw = 0; xw <= fs.width - maxsz.width && curl>2; nx++) {
|
||||
xw += 2 * (int)curl;
|
||||
curl *= shrink[0];
|
||||
}
|
||||
|
||||
int ny = 0;
|
||||
curl = maxsz.height;
|
||||
for(int yw = 0; yw <= fs.height - maxsz.height && curl>2; ny++) {
|
||||
yw += 2 * (int)curl;
|
||||
curl *= shrink[1];
|
||||
}
|
||||
|
||||
nx *= 2;
|
||||
ny *= 2;
|
||||
ZZCell[][] grid = new ZZCell[nx][ny];
|
||||
|
||||
int[] xsz = new int[nx+1];
|
||||
int[] ysz = new int[ny+1];
|
||||
|
||||
xsz[0] = maxsz.width / 2;
|
||||
xsz[1] = maxsz.width;
|
||||
ysz[0] = 2*maxsz.height;
|
||||
ysz[1] = maxsz.height;
|
||||
|
||||
curl = maxsz.width;
|
||||
for(int i=0; i<nx/2; i++) {
|
||||
xsz[nx/2-i + 1] = xsz[nx/2+i + 1] = (int)curl;
|
||||
curl *= shrink[0];
|
||||
}
|
||||
|
||||
curl = maxsz.height;
|
||||
for(int i=0; i<ny/2; i++) {
|
||||
ysz[ny/2-i + 1] = ysz[ny/2+i + 1] = (int)curl;
|
||||
curl *= shrink[1];
|
||||
}
|
||||
|
||||
int curi = 0;
|
||||
for(int i=0; i<nx+1; i++) { curi += xsz[i]; xsz[i] = curi; }
|
||||
curi = 0;
|
||||
for(int i=0; i<ny+1; i++) { curi += ysz[i]; ysz[i] = curi; }
|
||||
|
||||
int cx = nx / 2;
|
||||
int cy = ny / 2;
|
||||
|
||||
// Find which flobs to place where.
|
||||
grid[cx][cy] = accursed;
|
||||
|
||||
// XXX x expanded / y expanded!!!
|
||||
|
||||
// Negwards. Take headcells first.
|
||||
|
||||
Hashtable heads = new Hashtable();
|
||||
|
||||
ZZCell xhead = grid[0][cy] = accursed.h(dims[0], -1);
|
||||
ZZCell yhead = grid[cx][0] = accursed.h(dims[1], -1);
|
||||
heads.put(yhead, new Integer(cx));
|
||||
heads.put(xhead, new Integer(0));
|
||||
|
||||
LoopDetector ld = new LoopDetector();
|
||||
|
||||
ZZCell cur = accursed;
|
||||
for(int x = cx-1; x > 0 && cur != null; x--) { ld.detect(cur);
|
||||
cur = cur.s(dims[0], -1); if(cur == xhead) break;
|
||||
grid[x][cy] = cur;
|
||||
}
|
||||
|
||||
ld.reset();
|
||||
cur = accursed;
|
||||
for(int y = cy-1; y > 0 && cur != null; y--) { ld.detect(cur);
|
||||
cur = cur.s(dims[1], -1); if(cur == yhead) break;
|
||||
grid[cx][y] = cur;
|
||||
}
|
||||
|
||||
// Poswards
|
||||
ld.reset();
|
||||
cur = accursed;
|
||||
for(int x = cx+1; x < nx && cur != null; x++) { ld.detect(cur);
|
||||
grid[x][cy] = cur = cur.s(dims[0], 1);
|
||||
}
|
||||
ld.reset();
|
||||
cur = accursed;
|
||||
for(int y = cy+1; y < ny && cur != null; y++) { ld.detect(cur);
|
||||
grid[cx][y] = cur = cur.s(dims[1], 1);
|
||||
}
|
||||
|
||||
|
||||
// Other headcells
|
||||
for(int x = 1; x < nx; x ++)
|
||||
if(grid[x][cy] != null) {
|
||||
grid[x][0] = grid[x][cy].h(dims[1], -1);
|
||||
if(grid[x][0]!=null)
|
||||
heads.put(grid[x][0], new Integer(x));
|
||||
}
|
||||
for(int y = 1; y < ny; y ++)
|
||||
if(grid[cx][y] != null) {
|
||||
ZZCell c = grid[0][y] = grid[cx][y].h(dims[0], -1);
|
||||
if(c!=null)
|
||||
heads.put(c, new Integer(0));
|
||||
c = c.s(dims[0], 1);
|
||||
ld.reset();
|
||||
while(c!=null) { // Show other intersections
|
||||
ld.detect(c);
|
||||
Integer xpos = (Integer)heads.get(c.h(dims[1], -1));
|
||||
if(xpos!=null)
|
||||
grid[xpos.intValue()][y] = c;
|
||||
c = c.s(dims[0], 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
LineDecor.Builder bdline = new LineDecor.Builder(into, Color.red);
|
||||
bdline.startl(400, 1);
|
||||
|
||||
// Find out which cells are shown
|
||||
|
||||
Hashtable shown = new Hashtable();
|
||||
|
||||
for(int x = 0; x < nx; x++) {
|
||||
for( int y = 0; y < ny; y++) {
|
||||
if(grid[x][y]!=null)
|
||||
shown.put(grid[x][y], grid[x][y]);
|
||||
}
|
||||
}
|
||||
|
||||
// Render the flobs
|
||||
|
||||
for(int x = 0; x < nx; x ++) {
|
||||
for( int y = 0; y < ny; y ++) {
|
||||
if(grid[x][y] == null) continue;
|
||||
int xcoord = xsz[x];
|
||||
int ycoord = ysz[y];
|
||||
int width = xsz[x+1] - xcoord;
|
||||
int height = ysz[y+1] - ycoord;
|
||||
|
||||
if(x != 0 && y != 0 && heads.get(grid[x][y])!=null)
|
||||
continue;
|
||||
|
||||
Flob fl = fact.makeFlob(into, grid[x][y], grid[x][y],
|
||||
initmul * height / (float)maxsz.height,
|
||||
xcoord, ycoord, 1, width, height);
|
||||
/* if(x == 0 || y == 0)
|
||||
fl.flobPath="headcell";*/
|
||||
|
||||
// Place a red line if the neighbour isn't shown
|
||||
ZZCell c = grid[x][y];
|
||||
for(int dx=-1;dx<=1;dx+=2) {
|
||||
ZZCell n = c.s(dims[0], dx);
|
||||
if(n!=null && shown.get(n)==null
|
||||
&& (y!=0 || (x+dx>0 && x+dx<nx && grid[x+dx][y]==null))){
|
||||
int xc = xcoord + (width+dx*width)/2;
|
||||
int y1c = ycoord;
|
||||
int y2c = ycoord + height;
|
||||
|
||||
bdline.l(xc, y1c, xc, y2c);
|
||||
bdline.l(xc+dx, y1c, xc+dx, y2c);
|
||||
}
|
||||
}
|
||||
|
||||
for(int dy=-1;dy<=1;dy+=2) {
|
||||
ZZCell n = c.s(dims[1], dy);
|
||||
if(n!=null && shown.get(n)==null
|
||||
&& (x!=0 || (y+dy>0 && y+dy<ny && grid[x][y+dy]==null))){
|
||||
int x1c = xcoord;
|
||||
int x2c = xcoord + width;
|
||||
int yc = ycoord + (height+dy*height)/2;
|
||||
bdline.l(x1c, yc, x2c, yc);
|
||||
bdline.l(x1c, yc+dy, x2c, yc+dy);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Place red lines where the structure was collapsed
|
||||
/* if(x+1 < nx) {
|
||||
ZZCell c = grid[x][y];
|
||||
ZZCell cp = grid[x+1][y];
|
||||
if(cp != null && c.s(dims[0], 1)!=cp)
|
||||
bdline.l(xcoord+width, ycoord, xcoord+width, ycoord+height);
|
||||
}
|
||||
if(y+1 < ny) {
|
||||
ZZCell c = grid[x][y];
|
||||
ZZCell cp = grid[x][y+1];
|
||||
if(cp != null && c.s(dims[1], 1)!=cp)
|
||||
bdline.l(xcoord, ycoord+height, xcoord+width, ycoord+height);
|
||||
}*/
|
||||
|
||||
|
||||
|
||||
|
||||
/* // Show continuing ranks on edges
|
||||
if(x == 0 && grid[x][y].s(dims[0], -1)!=null)
|
||||
bdline.l(xcoord,ycoord,xcoord,ycoord+height);
|
||||
if(x+1 == nx && grid[x][y].s(dims[0], 1)!=null)
|
||||
bdline.l(xcoord+width,ycoord,xcoord+width,ycoord+height);
|
||||
|
||||
if(y == 0 && grid[x][y].s(dims[1], -1)!=null)
|
||||
bdline.l(xcoord,ycoord,xcoord+width,ycoord);
|
||||
if(y+1 == ny && grid[x][y].s(dims[1], 1)!=null)
|
||||
bdline.l(xcoord,ycoord+height,xcoord+width,ycoord+height);*/
|
||||
|
||||
}
|
||||
}
|
||||
bdline.endl();
|
||||
|
||||
// Do the dimensions.
|
||||
if(true)
|
||||
ZZUtil.showFlobDims(into, fact, view, 2);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// vim: set syntax=java :
|
||||
90
Java/flob/MultiView.zob
Normal file
90
Java/flob/MultiView.zob
Normal file
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
MultiView.zob
|
||||
*
|
||||
* You may use and distribute under the terms of either the GNU Lesser
|
||||
* General Public License, either version 2 of the license or,
|
||||
* at your choice, any later version. Alternatively, you may use and
|
||||
* distribute under the terms of the XPL.
|
||||
*
|
||||
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
|
||||
* the licenses.
|
||||
*
|
||||
* This software 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 README
|
||||
* file for more details.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Written by Benjamin Fallenstein
|
||||
*/
|
||||
|
||||
package org.gzigzag;
|
||||
import java.awt.*;
|
||||
import java.util.*;
|
||||
|
||||
/** A view that brings together different applitudes.
|
||||
*/
|
||||
|
||||
public class MultiView implements FlobView, ZOb {
|
||||
public static final String rcsid = "$Id: MultiView.zob,v 1.2 2000/12/28 22:46:02 bfallenstein Exp $";
|
||||
/** Should we print out debugging info? */
|
||||
public static boolean dbg = false;
|
||||
static final void p(String s) { if(dbg) pa(s); }
|
||||
static final void pa(String s) { System.out.println(s); }
|
||||
|
||||
STRUCTPARAMS {}
|
||||
|
||||
public void raster(final FlobSet into, final FlobFactory fact,
|
||||
final ZZCell win, final String[] dims,
|
||||
final ZZCell accursed) {
|
||||
final Hashtable had = new Hashtable();
|
||||
|
||||
ZZCell choice = null;
|
||||
ZZCell[] accapps = ApplitudeMgr.getApplitudes(accursed);
|
||||
ZZCell pref = ApplitudeMgr.getWindowApp(win);
|
||||
if(accapps.length == 0)
|
||||
choice = ApplitudeMgr.getFallback(win.getSpace());
|
||||
else {
|
||||
for(int i=0; i<accapps.length; i++) {
|
||||
if(accapps[i].equals(pref)) {
|
||||
choice = pref; break;
|
||||
}
|
||||
}
|
||||
if(choice == null)
|
||||
choice = accapps[0];
|
||||
}
|
||||
|
||||
final ZZCell app = choice;
|
||||
final Dimension size = new Dimension(into.getSize());
|
||||
fact.centerFlob(into, pref, pref, (float)1.5,
|
||||
new Point(size.width, size.height), 1, 1, 1);
|
||||
|
||||
FlobView view0 = ApplitudeMgr.getView(app);
|
||||
FlobSet set0 = into.create(size);
|
||||
view0.raster(set0, fact, win, dims, accursed);
|
||||
into.fetch(set0, 0, 0, 0, app);
|
||||
|
||||
set0.iterDepth(new FlobSet.DepthIter() {
|
||||
public void act(Flob[] flobs, int start, int n) {
|
||||
for(int i=start; i<start+n; i++) {
|
||||
Flob f = flobs[i];
|
||||
if(f.c == null || had.get(f.c) != null) continue;
|
||||
had.put(f.c, f.c);
|
||||
Point fc = f.getCenter();
|
||||
ZZCell[] apps = ApplitudeMgr.getApplitudes(f.c);
|
||||
for(int j=0; j<apps.length; j++) {
|
||||
if(apps[j].equals(app)) continue;
|
||||
FlobSet set = into.create(size);
|
||||
FlobView view = ApplitudeMgr.getView(apps[j]);
|
||||
view.raster(set, fact, win, dims, f.c);
|
||||
Flob g = set.findNearest(f, null);
|
||||
Point gc = g.getCenter();
|
||||
into.fetch(set, fc.x - gc.x + j, fc.y - gc.y + j,
|
||||
f.d+1, apps[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}, true);
|
||||
}
|
||||
}
|
||||
41
Java/flob/NullView.zob
Normal file
41
Java/flob/NullView.zob
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
NullRaster.zob
|
||||
*
|
||||
* You may use and distribute under the terms of either the GNU Lesser
|
||||
* General Public License, either version 2 of the license or,
|
||||
* at your choice, any later version. Alternatively, you may use and
|
||||
* distribute under the terms of the XPL.
|
||||
*
|
||||
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
|
||||
* the licenses.
|
||||
*
|
||||
* This software 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 README
|
||||
* file for more details.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Written by Antti-Juhani Kaijanaho
|
||||
*/
|
||||
|
||||
|
||||
package org.gzigzag;
|
||||
|
||||
/** A flobraster that just bails out (the default raster in case an
|
||||
unknown raster was requested). */
|
||||
public class NullView implements FlobView {
|
||||
public static final String rcsid = "$Id$";
|
||||
/** Should we print out debugging info? */
|
||||
public static boolean dbg = false;
|
||||
static final void p(String s) { if(dbg) pa(s); }
|
||||
static final void pa(String s) { System.out.println("(flob)NullRaster: " + s); }
|
||||
|
||||
STRUCTPARAMS {}
|
||||
|
||||
public void raster(FlobSet into, FlobFactory fact,
|
||||
ZZCell view, String[] dims, ZZCell accursed) {
|
||||
|
||||
throw new ZZError("null view invoked (please change view)");
|
||||
}
|
||||
}
|
||||
138
Java/flob/ParallelTextView.zob
Normal file
138
Java/flob/ParallelTextView.zob
Normal file
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
ParallelTextView.zob
|
||||
*
|
||||
* Copyright (c) 2000, Ted Nelson and Tuomas Lukka
|
||||
*
|
||||
* You may use and distribute under the terms of either the GNU Lesser
|
||||
* General Public License, either version 2 of the license or,
|
||||
* at your choice, any later version. Alternatively, you may use and
|
||||
* distribute under the terms of the XPL.
|
||||
*
|
||||
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
|
||||
* the licenses.
|
||||
*
|
||||
* This software 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 README
|
||||
* file for more details.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Written by Benjamin Fallenstein
|
||||
*/
|
||||
package org.gzigzag;
|
||||
import java.util.*;
|
||||
import java.awt.*;
|
||||
|
||||
/** A text cloud.
|
||||
*/
|
||||
|
||||
public class ParallelTextView implements FlobView, ZOb {
|
||||
public static final String rcsid = "$Id: ParallelTextView.zob,v 1.6 2000/12/11 09:03:03 raulir Exp $";
|
||||
public static boolean dbg = false;
|
||||
static void p(String s) { if(dbg) System.out.println(s); }
|
||||
static void pa(String s) { System.out.println(s); }
|
||||
|
||||
static RankTextView vr;
|
||||
|
||||
STRUCTPARAMS {
|
||||
}
|
||||
|
||||
public void raster(FlobSet into, FlobFactory fact,
|
||||
ZZCell view, final String[] dims, ZZCell accursed) {
|
||||
|
||||
Dimension d = into.getSize();
|
||||
int cy = d.height / 2;
|
||||
int width = d.width / 4;
|
||||
int xspace = width / 2;
|
||||
|
||||
if(vr == null) {
|
||||
vr = new RankTextView();
|
||||
vr.readParams(null);
|
||||
}
|
||||
vr.dim = dims[1];
|
||||
vr.width = width;
|
||||
|
||||
ZZCell[] streams = new ZZCell[] {
|
||||
accursed.s(dims[0], -1),
|
||||
accursed,
|
||||
accursed.s(dims[0], 1),
|
||||
};
|
||||
|
||||
int offs = ZZCursorReal.getOffs(view);
|
||||
if(offs == ZZCursorReal.NO_OFFSET) offs = 0;
|
||||
|
||||
for(int i=0; i < 3; i++) {
|
||||
if(streams[i] == null) continue;
|
||||
int x = i * (width + xspace);
|
||||
vr.raster(into, streams[i], i==1 ? offs : 0, false, x, cy);
|
||||
}
|
||||
|
||||
// Now, the links
|
||||
|
||||
final FlobSet f = (FlobSet)into; // XXX
|
||||
final LineDecor.Builder ldb = new LineDecor.Builder(f, Color.red);
|
||||
final Hashtable flobtable = new Hashtable();
|
||||
|
||||
f.iterDepth(new FlobSet.DepthIter() {
|
||||
public void act(Flob[] flobs, int start, int n) {
|
||||
for(int i=start; i<start+n; i++) {
|
||||
Flob flb = flobs[i];
|
||||
if(flb.c == null) continue;
|
||||
// if(((SpanFlob)flb).getPrev() != null) continue;
|
||||
Vector fs = (Vector) flobtable.get(flb.c);
|
||||
if(fs == null) {
|
||||
fs = new Vector();
|
||||
flobtable.put(flb.c, fs);
|
||||
}
|
||||
fs.addElement(flb);
|
||||
}
|
||||
}
|
||||
}, true);
|
||||
|
||||
f.iterDepth(new FlobSet.DepthIter() {
|
||||
public void act(Flob[] flobs, int start, int n) {
|
||||
|
||||
ldb.startl(2*n, flobs[start].d + 1);
|
||||
|
||||
for(int i=start; i<start+n; i++) {
|
||||
Flob cur = flobs[i];
|
||||
ZZCell c = cur.c;
|
||||
p(" cell: "+c+" "+(c!=null?c.getText():""));
|
||||
if(!(cur instanceof SpanFlob)) continue;
|
||||
p(" is span flob");
|
||||
if(c == null) continue;
|
||||
SpanFlob spanf = (SpanFlob)cur;
|
||||
// if(spanf.getPrev() != null) continue;
|
||||
p(" doesn't have prev");
|
||||
{ // XXX dedent
|
||||
ZZCell neigh = c.s(dims[0], 1);
|
||||
p(" Neigh: "+neigh+" "+
|
||||
(neigh!=null?neigh.getText():""));
|
||||
if(neigh == null) continue;
|
||||
Vector nflbs = (Vector) flobtable.get(neigh);
|
||||
if(nflbs == null) continue;
|
||||
// XXX show connections to non-shown cells!
|
||||
for(Enumeration e = nflbs.elements();
|
||||
e.hasMoreElements();) {
|
||||
Flob nf = (Flob) e.nextElement();
|
||||
SpanFlob nsf = (SpanFlob) nf;
|
||||
Flob from=cur, to=nf;
|
||||
ldb.l(
|
||||
from.x + from.w,
|
||||
from.y + from.h / 2,
|
||||
to.x,
|
||||
to.y + to.h / 2
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ldb.endl();
|
||||
}
|
||||
}, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// vim: set syntax=java :
|
||||
307
Java/flob/RankTextView.zob
Normal file
307
Java/flob/RankTextView.zob
Normal file
@@ -0,0 +1,307 @@
|
||||
/*
|
||||
VStreamRaster.zob
|
||||
*
|
||||
* Copyright (c) 1999-2000, Ted Nelson and Tuomas Lukka
|
||||
*
|
||||
* You may use and distribute under the terms of either the GNU Lesser
|
||||
* General Public License, either version 2 of the license or,
|
||||
* at your choice, any later version. Alternatively, you may use and
|
||||
* distribute under the terms of the XPL.
|
||||
*
|
||||
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
|
||||
* the licenses.
|
||||
*
|
||||
* This software 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 README
|
||||
* file for more details.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Written by Tuomas Lukka
|
||||
*/
|
||||
|
||||
package org.gzigzag;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.util.*;
|
||||
|
||||
/** A raster of flowing text.
|
||||
* The FlobRaster is implemented mostly for testing purposes - this class
|
||||
* would mostly be called from another raster.
|
||||
*/
|
||||
|
||||
public class RankTextView implements FlobView, ZOb {
|
||||
public static final String rcsid = "$Id$";
|
||||
public static boolean dbg = false;
|
||||
static final void p(String s) { if(dbg) System.out.println(s); }
|
||||
static final void pa(String s) { System.out.println(s); }
|
||||
|
||||
STRUCTPARAMS {
|
||||
/** The width of the flowing text at maximum. Negative value
|
||||
means that the width of the window should be used. */
|
||||
int width
|
||||
= 300;
|
||||
|
||||
/** The font for the maximal line. */
|
||||
ScalableFont font
|
||||
= new ScalableFont("SansSerif", Font.PLAIN, 16);
|
||||
|
||||
/** The half-width of the bulge. */
|
||||
int bulge
|
||||
= 10;
|
||||
|
||||
/** Whether to show cuts. */
|
||||
boolean cuts
|
||||
= true;
|
||||
|
||||
/** Which dimension to use. */
|
||||
String dim
|
||||
= "d.2";
|
||||
|
||||
/** Whether to billow the text. */
|
||||
boolean billow
|
||||
= true;
|
||||
|
||||
/** Whether to show XOR cursors. */
|
||||
boolean xor
|
||||
= true;
|
||||
|
||||
/** The backround colour for all flobs (or null if determined
|
||||
from the cursors. */
|
||||
Color bgcolor
|
||||
= null;
|
||||
|
||||
}
|
||||
|
||||
protected Font getfont(int scale) {
|
||||
return font.getFont(scale);
|
||||
}
|
||||
protected FontMetrics getfontmet(int scale) {
|
||||
return font.getFontMetrics(scale);
|
||||
}
|
||||
|
||||
|
||||
SimpleLineInfo.Layout layb = new LayBillow();
|
||||
SimpleLineInfo.Layout layf = new LayFlat();
|
||||
SimpleLineBreaker brk = new SimpleLineBreaker();
|
||||
|
||||
protected int getFontScale(int line, boolean doBillow) {
|
||||
int w = (doBillow ? layb : layf).getWidth(line);
|
||||
|
||||
return (1000*w)/width;
|
||||
|
||||
}
|
||||
|
||||
class LayBillow implements SimpleLineInfo.Layout {
|
||||
public final FontMetrics getFontMetrics(int line) {
|
||||
return getfontmet(getFontScale(line, true));
|
||||
}
|
||||
public final int getWidth(int line) {
|
||||
if(bulge <= 0) return width;
|
||||
float bfunc = (float)(
|
||||
1.0/ ( 1 + (line * (float)line) / (bulge * bulge) ) );
|
||||
return (int)(bfunc * width);
|
||||
}
|
||||
public final int getCenterLine() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
class LayFlat implements SimpleLineInfo.Layout {
|
||||
public final FontMetrics getFontMetrics(int line) {
|
||||
return getfontmet(1000);
|
||||
}
|
||||
public final int getWidth(int line) {
|
||||
return width;
|
||||
}
|
||||
public final int getCenterLine() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/** Raster an area.
|
||||
* Returns a bounding rectangle for the text plotted.
|
||||
*/
|
||||
public Rectangle raster(FlobSet into, ZZCell c, int offs, boolean doBillow,
|
||||
int startx, int starty, int xormode) {
|
||||
if (width < 0) width = into.getSize().width;
|
||||
|
||||
Rectangle res = new Rectangle();
|
||||
|
||||
|
||||
// read the whole string first
|
||||
int soffs = -1;
|
||||
StringBuffer s = new StringBuffer();
|
||||
ZZCell head = c.h(dim, -1);
|
||||
boolean first = true;
|
||||
for(ZZCell h = head;
|
||||
h != null && (first || h!=head); h = h.s(dim, 1)) {
|
||||
first = false;
|
||||
if(h == c)
|
||||
soffs = offs + s.length();
|
||||
s.append(h.getText());
|
||||
}
|
||||
if(soffs < 0)
|
||||
throw new ZZError("??? ARGH");
|
||||
String txt = s.toString();
|
||||
SimpleLineInfo sli = new SimpleLineInfo(txt, soffs,
|
||||
(doBillow?layb:layf));
|
||||
int[] linestops = brk.breakLines(sli);
|
||||
p("Breaklines: "+offs);
|
||||
for(int i=0; i<linestops.length; i++)
|
||||
p("Line: "+linestops[i]);
|
||||
for(int i=-10; i<=10; i++) {
|
||||
p("WFM: "+layb.getWidth(i)+" "+getFontScale(i, doBillow));
|
||||
}
|
||||
|
||||
int ctr = - linestops[0];
|
||||
|
||||
|
||||
/** Current Y offset for the loop. */
|
||||
int cury = starty;
|
||||
// Calculate the starting Y coordinate
|
||||
for(int i = ctr; i>=0; i--) {
|
||||
cury -= getfontmet(getFontScale(i-ctr, doBillow)).getHeight();
|
||||
}
|
||||
|
||||
res.x = startx; res.width = width;
|
||||
res.y = cury;
|
||||
|
||||
// Downwards from center.
|
||||
// start-splitcellflob needs very careful attention.
|
||||
|
||||
/** Current offset in the whole string.
|
||||
*/
|
||||
int curoffs = 0;
|
||||
/** Current line.
|
||||
*/
|
||||
int curline = 0;
|
||||
|
||||
/** Current X-coordinate.
|
||||
*/
|
||||
int curx = startx;
|
||||
|
||||
int fi = getFontScale(curline - ctr, doBillow);
|
||||
Font f = getfont(fi);
|
||||
FontMetrics fm = getfontmet(fi);
|
||||
|
||||
SplitCellFlob1 latest = null;
|
||||
|
||||
first = true;
|
||||
for(ZZCell h = head;
|
||||
h != null && (first || h != head); h = h.s(dim, 1)) {
|
||||
first = false;
|
||||
|
||||
final String st = h.getText();
|
||||
final int len = st.length();
|
||||
int nth = 0;
|
||||
SplitCellFlob1 parent = null;
|
||||
|
||||
// Find the cursors on this cell. Only one is shown.
|
||||
int curs = ZZCursorReal.NO_OFFSET;
|
||||
ZZCell ccurs = h;
|
||||
while((ccurs = ccurs.s("d.cursor", 1))!=null) {
|
||||
curs = ZZCursorReal.getOffs(ccurs);
|
||||
if(curs != ZZCursorReal.NO_OFFSET) break;
|
||||
}
|
||||
|
||||
if(h.s("d.cut", 1) != null) {
|
||||
// There was a cut.
|
||||
into.add(new LineDecor(curx, cury, curx, cury+fm.getHeight(),
|
||||
Color.red, 1));
|
||||
}
|
||||
|
||||
while(curoffs + len - nth > linestops[curline+1]) {
|
||||
p("Parent: "+nth+" "+len+" "+curline+" "+linestops[curline+1]);
|
||||
SplitCellFlob1 cur = new SplitCellFlob1(
|
||||
curx, cury, 100, fm.stringWidth(st.substring(nth,
|
||||
nth+
|
||||
(linestops[curline+1] - curoffs))),
|
||||
fm.getHeight(), h, f, fm, parent,
|
||||
nth, linestops[curline+1]-curoffs, xormode, bgcolor);
|
||||
if(bgcolor == null) cur.showCursor();
|
||||
cur.setPrev(latest); latest = cur;
|
||||
if(curs != ZZCursorReal.NO_OFFSET)
|
||||
addCurs(into, cur, curs);
|
||||
parent = cur;
|
||||
into.add(cur);
|
||||
|
||||
// Split it.
|
||||
nth += linestops[curline+1] - curoffs;
|
||||
curoffs = linestops[curline+1];
|
||||
curline ++;
|
||||
cury += fm.getHeight();
|
||||
curx = startx;
|
||||
fi = getFontScale(curline - ctr, doBillow);
|
||||
f = getfont(fi);
|
||||
fm = getfontmet(fi);
|
||||
if(curline >= linestops.length - 1) {
|
||||
p("LAST LINE: ALL OUT");
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(curline >= linestops.length - 1)
|
||||
break;
|
||||
|
||||
p("Last: "+nth+" "+len+" "+curline+" "+linestops[curline+1]+" "+
|
||||
st.length());
|
||||
int w = 0;
|
||||
String substr = st.substring(nth, len);
|
||||
p("Substr: "+substr);
|
||||
SplitCellFlob1 last = new SplitCellFlob1(
|
||||
curx, cury, 100,
|
||||
(w = fm.stringWidth(substr)),
|
||||
fm.getHeight(), h, f, fm, parent, nth, len-nth, xormode, bgcolor);
|
||||
if(bgcolor == null) last.showCursor();
|
||||
last.setPrev(latest); latest = last;
|
||||
|
||||
if(curs != ZZCursorReal.NO_OFFSET)
|
||||
addCurs(into, last, curs);
|
||||
curoffs += len-nth;
|
||||
curx += w;
|
||||
into.add(last);
|
||||
}
|
||||
p("FINISHED");
|
||||
res.height = cury - res.y + fm.getHeight();
|
||||
return res;
|
||||
}
|
||||
|
||||
public Rectangle raster(FlobSet into, ZZCell c, int offs, boolean doBillow,
|
||||
int startx, int starty) {
|
||||
return raster(into, c, offs, doBillow, startx, starty,
|
||||
SplitCellFlob1.XOR_NO);
|
||||
}
|
||||
|
||||
private void addCurs(FlobSet into, SplitCellFlob1 sf, int ind) {
|
||||
if(!(ind >= sf.start && ind <= sf.start + sf.n))
|
||||
return;
|
||||
int x = sf.getStrX(ind);
|
||||
if(x >= 0)
|
||||
into.add(new LineDecor(x, sf.y, x, sf.y+sf.h,
|
||||
Color.black, sf.d));
|
||||
}
|
||||
|
||||
public void raster(FlobSet into, FlobFactory fact,
|
||||
ZZCell view, String[] dims, ZZCell accursed) {
|
||||
ZZCell c = ZZCursorReal.get(view);
|
||||
int offs = ZZCursorReal.getOffs(view);
|
||||
int xormode = SplitCellFlob1.XOR_LINE;
|
||||
if(offs == ZZCursor.NO_OFFSET) {
|
||||
offs = 0;
|
||||
xormode = SplitCellFlob1.XOR_SOLID;
|
||||
}
|
||||
|
||||
if(!xor) xormode = SplitCellFlob1.XOR_NO;
|
||||
|
||||
Dimension d = into.getSize();
|
||||
int cy = d.height / 2;
|
||||
|
||||
raster(into, c, offs, billow, 0, cy, xormode);
|
||||
}
|
||||
|
||||
// public VStreamRaster() { }
|
||||
|
||||
}
|
||||
|
||||
// vim: set syntax=java :
|
||||
88
Java/flob/Renderable.java
Normal file
88
Java/flob/Renderable.java
Normal file
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
Renderable.java
|
||||
*
|
||||
* Copyright (c) 2000, Ted Nelson and Tuomas Lukka
|
||||
*
|
||||
* You may use and distribute under the terms of either the GNU Lesser
|
||||
* General Public License, either version 2 of the license or,
|
||||
* at your choice, any later version. Alternatively, you may use and
|
||||
* distribute under the terms of the XPL.
|
||||
*
|
||||
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
|
||||
* the licenses.
|
||||
*
|
||||
* This software 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 README
|
||||
* file for more details.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Written by Tuomas Lukka
|
||||
*/
|
||||
package org.gzigzag;
|
||||
import java.util.*;
|
||||
import java.awt.*;
|
||||
|
||||
|
||||
public abstract class Renderable {
|
||||
public static final String rcsid = "$Id: Renderable.java,v 1.10 2001/03/17 20:13:08 bfallenstein Exp $";
|
||||
|
||||
public int d;
|
||||
|
||||
/** Render this thing.
|
||||
*/
|
||||
abstract public void render(Graphics g);
|
||||
|
||||
/** Render this thing.
|
||||
* Simply calls render(g).
|
||||
* @param orig The top-level graphics object without translations,
|
||||
* clippings, rotations, etc.
|
||||
*/
|
||||
public void render(Graphics g, Graphics orig) { render(g); }
|
||||
|
||||
/** Translate the coordinates of this Renderable by (x, y)
|
||||
* I.e., add x from the x-coordinate and y from the y-coordinate.
|
||||
* This is used to translate between coordinate systems.
|
||||
* @returns False if translating is not supported.
|
||||
*/
|
||||
public boolean translate(int x, int y) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/** Do a stable depth-sort of renderables.
|
||||
* Of two renderables on the same depth, the relative order remains.
|
||||
* Uses radix sort for extreme speed.
|
||||
*/
|
||||
static public void depthSort(Renderable[] it, int nit) {
|
||||
Renderable[][] ftmp = new Renderable[][] { it, new Renderable[nit] };
|
||||
Renderable[][] ftmp2 = new Renderable[2][nit];
|
||||
Renderable[][] fs;
|
||||
int[] n = new int[] { nit, 0 };
|
||||
int[] newn = new int[2];
|
||||
int[] nex = null;
|
||||
int mx = 0;
|
||||
for(int i=0; i<nit; i++) {
|
||||
if(it[i].d > mx) mx = it[i].d;
|
||||
}
|
||||
for(int bit = 1; mx >= bit && bit!=0; bit <<= 1) {
|
||||
for(int bin=0; bin<2; bin++) {
|
||||
for(int i=0; i<n[bin]; i++) {
|
||||
if(ftmp[bin][i] == null) continue;
|
||||
int ind = (((ftmp[bin][i].d & bit) == 0) ? 0 : 1);
|
||||
ftmp2[ind][newn[ind]++] = ftmp[bin][i];
|
||||
}
|
||||
}
|
||||
fs = ftmp2; ftmp2 = ftmp; ftmp = fs;
|
||||
nex = n; n = newn; newn = nex;
|
||||
newn[0] = newn[1] = 0;
|
||||
}
|
||||
for(int i=0; i<nit-n[0]; i++)
|
||||
ftmp[0][n[0]+i] = ftmp[1][i];
|
||||
|
||||
if(it != ftmp[0]) {
|
||||
System.arraycopy(ftmp[0], 0, it, 0, nit);
|
||||
}
|
||||
}
|
||||
}
|
||||
125
Java/flob/RowColView.zob
Normal file
125
Java/flob/RowColView.zob
Normal file
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
RowColRaster.zob
|
||||
*
|
||||
* Copyright (c) 2000, Ted Nelson and Tuomas Lukka
|
||||
*
|
||||
* You may use and distribute under the terms of either the GNU Lesser
|
||||
* General Public License, either version 2 of the license or,
|
||||
* at your choice, any later version. Alternatively, you may use and
|
||||
* distribute under the terms of the XPL.
|
||||
*
|
||||
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
|
||||
* the licenses.
|
||||
*
|
||||
* This software 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 README
|
||||
* file for more details.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Written by Tuomas Lukka
|
||||
*/
|
||||
|
||||
|
||||
package org.gzigzag;
|
||||
import java.awt.*;
|
||||
import java.util.*;
|
||||
|
||||
public class RowColView implements FlobView, ZOb {
|
||||
public static final String rcsid = "$Id$";
|
||||
public static boolean dbg = false;
|
||||
static final void p(String s) { if(dbg) System.out.println(s); }
|
||||
static final void pa(String s) { System.out.println(s); }
|
||||
|
||||
STRUCTPARAMS {
|
||||
boolean repeat
|
||||
= false;
|
||||
|
||||
boolean row
|
||||
= false;
|
||||
|
||||
ZOb geom
|
||||
= new MagGrid();
|
||||
}
|
||||
|
||||
void place(FlobFactory fact,
|
||||
FlobSet f, ZZCell c, Dimension ideal, Rectangle where) {
|
||||
float fract = (float)(where.height / (float)ideal.height);
|
||||
fact.makeFlob(f, c, c, fract, where.x, where.y, 1, where.width,
|
||||
where.height);
|
||||
|
||||
}
|
||||
|
||||
FlobDecorator linker = new StdLinks();
|
||||
|
||||
public void raster(final FlobSet into, final FlobFactory fact,
|
||||
ZZCell view, String[] dims, ZZCell accursed) {
|
||||
final GridGeom geom = (GridGeom)this.geom;
|
||||
final Dimension ideal = fact.getSize(null, 1);
|
||||
final Dimension gs = geom.setSizes(ideal, into.getSize());
|
||||
|
||||
final Hashtable done = new Hashtable();
|
||||
final Rectangle rect = new Rectangle();
|
||||
|
||||
final int cx = gs.width / 2;
|
||||
final int cy = gs.height / 2;
|
||||
|
||||
final ZZCell[] col = new ZZCell[row ? gs.height : gs.width];
|
||||
|
||||
final int cmain = (row ? cy : cx);
|
||||
final int cother = (row ? cx : cy);
|
||||
|
||||
|
||||
// Do the dimensions.
|
||||
// Must do these first so that they get to be shown on top.
|
||||
if(true)
|
||||
ZZUtil.showFlobDims(into, fact, view, 3);
|
||||
|
||||
|
||||
// Do the single row/column
|
||||
ZZIter.alternate(accursed, true, dims[(row ? 1 : 0)], 1,
|
||||
new ZZIter.NIter() {
|
||||
public boolean go(ZZCell c, int nth) {
|
||||
nth += cmain;
|
||||
if(nth < 0 || nth >= col.length) return false;
|
||||
if(!repeat && done.get(c) != null) return false;
|
||||
col[nth] = c;
|
||||
done.put(c, c);
|
||||
if(row)
|
||||
geom.getCell(cother, nth, rect);
|
||||
else
|
||||
geom.getCell(nth, cother, rect);
|
||||
place(fact, into, c, ideal, rect);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
final int lother = (row ? gs.width : gs.height);
|
||||
|
||||
for(int i = 0; i<col.length; i++) {
|
||||
final int coord = i;
|
||||
ZZIter.alternate(col[i], false, dims[(row ? 0 : 1)], 1,
|
||||
new ZZIter.NIter() {
|
||||
public boolean go(ZZCell c, int nth) {
|
||||
nth += cother;
|
||||
if(nth < 0 || nth >= lother) return false;
|
||||
if(!repeat && done.get(c) != null) return false;
|
||||
done.put(c, c);
|
||||
if(row)
|
||||
geom.getCell(nth, coord, rect);
|
||||
else
|
||||
geom.getCell(coord, nth, rect);
|
||||
place(fact, into, c, ideal, rect);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
linker.decorate(into, "", view);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
// vim: set syntax=java :
|
||||
148
Java/flob/SceneFlob.java
Normal file
148
Java/flob/SceneFlob.java
Normal file
@@ -0,0 +1,148 @@
|
||||
/*
|
||||
SceneFlob.java
|
||||
*
|
||||
* Copyright (c) 2001, Ted Nelson and Tuomas Lukka
|
||||
*
|
||||
* You may use and distribute under the terms of either the GNU Lesser
|
||||
* General Public License, either version 2 of the license or,
|
||||
* at your choice, any later version. Alternatively, you may use and
|
||||
* distribute under the terms of the XPL.
|
||||
*
|
||||
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
|
||||
* the licenses.
|
||||
*
|
||||
* This software 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 README
|
||||
* file for more details.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Written by Tuomas Lukka
|
||||
*/
|
||||
package org.gzigzag;
|
||||
import java.util.*;
|
||||
import java.awt.*;
|
||||
|
||||
/** Flob which contains flobset, possibly transformed.
|
||||
* This is subclassed by e.g. ZZDrawingJ2D.
|
||||
*/
|
||||
|
||||
public abstract class SceneFlob extends BoxedFlob {
|
||||
public static final String rcsid = "$Id: SceneFlob.java,v 1.8 2001/03/18 17:50:16 bfallenstein Exp $";
|
||||
public static final boolean dbg = true;
|
||||
static final void p(String s) { if(dbg) System.out.println(s); }
|
||||
static final void pa(String s) { System.out.println(s); }
|
||||
|
||||
FlobSet sc;
|
||||
|
||||
public SceneFlob(int x, int y, int d, int w, int h, ZZCell c, FlobSet sc) {
|
||||
super(x,y,d,w,h,c);
|
||||
this.sc = sc;
|
||||
sc.sflob = this;
|
||||
}
|
||||
|
||||
/** The flobs that are important to interpolate
|
||||
* even when level-of-detail is small
|
||||
*/
|
||||
Flob[] important;
|
||||
|
||||
/** Set the important-to-interpolate flobs.
|
||||
*/
|
||||
public void setImportant(Flob[] what) {
|
||||
important = what;
|
||||
}
|
||||
|
||||
/** Whether this is a focused sceneflob, i.e.whether level-of-detail
|
||||
* is high.
|
||||
*/
|
||||
boolean focus;
|
||||
|
||||
public void setFocus(boolean focus) {
|
||||
this.focus = focus;
|
||||
}
|
||||
|
||||
/** The other sceneflob we are currently prepared to interpolate to.
|
||||
*/
|
||||
SceneFlob interpPrep;
|
||||
|
||||
/** The scene flob this one is in.
|
||||
* This is needed to convert coordinates to top-level; and that is needed
|
||||
* to create connections between windows.
|
||||
*/
|
||||
SceneFlob parent;
|
||||
|
||||
/** Transform the given points between the internal and external coordinates.
|
||||
* @param toExt Whether to transform internal to external or vice versa.
|
||||
*/
|
||||
public abstract void transform(double[] srcPtr, double[]dstPts, boolean toExt);
|
||||
|
||||
/** Transform the given point between the internal and external coordinates.
|
||||
* @param toExt Whether to transform internal to external or vice versa.
|
||||
*/
|
||||
public abstract Point transform(Point src, Point dst, boolean toExt);
|
||||
|
||||
/** Transform the given points between the internal and top-level coordinates.
|
||||
* @param toTop Whether to transform internal to top-level or vice versa.
|
||||
*/
|
||||
public void transformTop(double[] srcPtr, double[] dstPts, boolean toTop) {
|
||||
if(toTop) transform(srcPtr, dstPts, true);
|
||||
if(parent != null)
|
||||
parent.transformTop(srcPtr, dstPts, toTop);
|
||||
if(!toTop) transform(srcPtr, dstPts, false);
|
||||
}
|
||||
|
||||
/** Transform the given point between the internal and top-level coordinates.
|
||||
* @param toTop Whether to transform internal to top-level or vice versa.
|
||||
*/
|
||||
public Point transformTop(Point src, Point dst, boolean toTop) {
|
||||
if(toTop) transform(src, dst, true);
|
||||
if(parent != null)
|
||||
parent.transformTop(src, dst, toTop);
|
||||
if(!toTop) transform(src, dst, false);
|
||||
return dst;
|
||||
}
|
||||
|
||||
/** Make this graphics so that we can render into it with the correct
|
||||
* transformation.
|
||||
*/
|
||||
abstract void prepareGraphics(Graphics g, float interpFract);
|
||||
|
||||
public void render(Graphics g0) { render(g0, g0); }
|
||||
public void render(Graphics g0, Graphics orig) {
|
||||
Graphics g = g0.create();
|
||||
prepareGraphics(g, 0);
|
||||
sc.render(g, orig);
|
||||
g.dispose();
|
||||
}
|
||||
|
||||
public void renderInterp(Graphics g0, float fract) {
|
||||
if(!(interpTo instanceof SceneFlob)) return;
|
||||
// p("sceneflob renderinterp");
|
||||
// Here we test the level-of-detail stuff.
|
||||
if(interpTo != interpPrep) {
|
||||
interpPrep = (SceneFlob)interpTo;
|
||||
// p("Prepinterp sceneflob: "+focus+" "+interpPrep.focus+" "+important);
|
||||
if(focus || interpPrep.focus || important == null)
|
||||
sc.prepareInterp(interpPrep.sc);
|
||||
else
|
||||
sc.prepareInterp(interpPrep.sc, important);
|
||||
}
|
||||
Graphics g = g0.create();
|
||||
prepareGraphics(g, fract);
|
||||
sc.renderInterp(g, ((SceneFlob)interpTo).sc, fract);
|
||||
g.dispose();
|
||||
}
|
||||
|
||||
public boolean isInterpUseful() { return true; }
|
||||
|
||||
public Object hit(int x, int y) {
|
||||
Point p = new Point(x,y);
|
||||
Point d = new Point();
|
||||
transform(p,d, false);
|
||||
return sc.getObjectAt(d.x, d.y);
|
||||
}
|
||||
|
||||
public FlobSet getFlobSet(){ return sc;}
|
||||
|
||||
}
|
||||
256
Java/flob/SimpleBeamer.zob
Normal file
256
Java/flob/SimpleBeamer.zob
Normal file
@@ -0,0 +1,256 @@
|
||||
/*
|
||||
SimpleBeamer.zob
|
||||
*
|
||||
* Copyright (c) 1999-2000, Ted Nelson and Tuomas Lukka
|
||||
*
|
||||
* You may use and distribute under the terms of either the GNU Lesser
|
||||
* General Public License, either version 2 of the license or,
|
||||
* at your choice, any later version. Alternatively, you may use and
|
||||
* distribute under the terms of the XPL.
|
||||
*
|
||||
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
|
||||
* the licenses.
|
||||
*
|
||||
* This software 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 README
|
||||
* file for more details.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Written by Tuomas Lukka
|
||||
*/
|
||||
|
||||
|
||||
package org.gzigzag;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.util.*;
|
||||
|
||||
/** A decorator which draws beams between overlapping SpanFlobs.
|
||||
* This is a tricky job: among other things, we are responsible for
|
||||
* the overall aesthetic effect of beams.
|
||||
* Currently, we try to draw the beams between the topmost
|
||||
* flobs last so that the beams have a consistent ordering w.r.t.
|
||||
* the Z axis. This is <em>not</em> trivial, since we also have to
|
||||
* draw neighbouring beams using the same color.
|
||||
*/
|
||||
|
||||
public class SimpleBeamer implements FlobDecorator {
|
||||
public static final String rcsid = "$Id: SimpleBeamer.zob,v 1.7 2000/09/19 10:31:59 ajk Exp $";
|
||||
public static boolean dbg = false;
|
||||
static final void p(String s) { if(dbg) System.out.println(s); }
|
||||
static final void pa(String s) { System.out.println(s); }
|
||||
|
||||
STRUCTPARAMS {
|
||||
|
||||
/** The depth where to put the beam graphics.
|
||||
*/
|
||||
int depth
|
||||
= 1000;
|
||||
|
||||
}
|
||||
|
||||
// Used for checking whether the connection between two spans
|
||||
// is handled already.
|
||||
private class Pair {
|
||||
Object a; Object b;
|
||||
public Pair(Object a, Object b) {
|
||||
this.a = a;
|
||||
this.b = b;
|
||||
}
|
||||
public int hashCode() {
|
||||
return a.hashCode() ^ b.hashCode();
|
||||
}
|
||||
public boolean equals(Object o) {
|
||||
Pair p = (Pair)o;
|
||||
return (a==p.a && b==p.b) || (b==p.a && a==p.b);
|
||||
}
|
||||
}
|
||||
|
||||
static public Color getSpanColor() {
|
||||
return new Color(
|
||||
(float)(Math.random() + 1) / 2,
|
||||
(float)(Math.random() + 1) / 2,
|
||||
(float)(Math.random() + 1) / 2
|
||||
);
|
||||
}
|
||||
|
||||
int[] xy = new int[16];
|
||||
|
||||
protected void putBeam(BeamDecor.Builder bb,
|
||||
SpanFlob[] sfs, Span[] sps,
|
||||
Color c) {
|
||||
p("Putbeam");
|
||||
int ssep = (int)(sps[0].getStartOffs() - sps[1].getStartOffs());
|
||||
int esep = (int)(sps[0].getEndOffs() - sps[1].getEndOffs());
|
||||
|
||||
int x0=0, x1=0, w0=(int)sps[0].length(), w1=(int)sps[1].length();
|
||||
|
||||
if(ssep > 0) x1 = ssep;
|
||||
else x0 = -ssep;
|
||||
|
||||
if(esep > 0) w0 -= esep;
|
||||
else w1 += esep;
|
||||
|
||||
Rectangle r0 = sfs[0].getRectangle(x0, w0);
|
||||
Rectangle r1 = sfs[1].getRectangle(x1, w1);
|
||||
|
||||
// Then, some difficult manipulation to get the points.
|
||||
|
||||
Rectangle a=null;
|
||||
|
||||
// left side
|
||||
if(r0.x < r1.x) { a = r0; } else { a = r1; }
|
||||
xy[0] = a.x; xy[8] = a.y;
|
||||
xy[1] = a.x; xy[9] = a.y+a.height;
|
||||
// bottom side
|
||||
if(r0.y+r0.height > r1.y+r1.height) { a = r0; } else { a = r1; }
|
||||
xy[2] = a.x; xy[10] = a.y+a.height;
|
||||
xy[3] = a.x+a.width; xy[11] = a.y+a.height;
|
||||
// right side
|
||||
if(r0.x+r0.width > r1.x+r1.width) { a = r0; } else { a = r1; }
|
||||
xy[4] = a.x+a.width; xy[12] = a.y+a.height;
|
||||
xy[5] = a.x+a.width; xy[13] = a.y;
|
||||
// top
|
||||
if(r0.y < r1.y) { a = r0; } else { a = r1; }
|
||||
xy[6] = a.x+a.width; xy[14] = a.y;
|
||||
xy[7] = a.x; xy[15] = a.y;
|
||||
|
||||
bb.b(xy, c);
|
||||
|
||||
}
|
||||
|
||||
/** Return: whether to continue.
|
||||
*/
|
||||
static boolean moveBack( SpanFlob[] sfs,
|
||||
Span[] spans) {
|
||||
long l1 = spans[0].getStartOffs();
|
||||
long l2 = spans[1].getStartOffs();
|
||||
if(l1 == l2) {
|
||||
// Check if previous spans end at same point.
|
||||
sfs[0] = sfs[0].getPrev(); if(sfs[0] == null) return false;
|
||||
sfs[1] = sfs[1].getPrev(); if(sfs[1] == null) return false;
|
||||
spans[0] = sfs[0].getSpan(); if(spans[0] == null) return false;
|
||||
spans[1] = sfs[1].getSpan(); if(spans[1] == null) return false;
|
||||
if(spans[0].getEndOffs() != spans[1].getEndOffs()) return false;
|
||||
return true;
|
||||
}
|
||||
if(l1 > l2) {
|
||||
Span tmp = spans[0];
|
||||
sfs[0] = sfs[0].getPrev(); if(sfs[0] == null) return false;
|
||||
spans[0] = sfs[0].getSpan(); if(spans[0] == null) return false;
|
||||
return spans[0].isAppendable(tmp);
|
||||
} else {
|
||||
Span tmp = spans[1];
|
||||
sfs[1] = sfs[1].getPrev(); if(sfs[1] == null) return false;
|
||||
spans[1] = sfs[1].getSpan(); if(spans[1] == null) return false;
|
||||
return spans[1].isAppendable(tmp);
|
||||
}
|
||||
}
|
||||
static boolean moveForw( SpanFlob[] sfs,
|
||||
Span[] spans) {
|
||||
long l1 = spans[0].getEndOffs();
|
||||
long l2 = spans[1].getEndOffs();
|
||||
if(l1 == l2) {
|
||||
// Check if previous spans end at same point.
|
||||
sfs[0] = sfs[0].getNext(); if(sfs[0] == null) return false;
|
||||
sfs[1] = sfs[1].getNext(); if(sfs[1] == null) return false;
|
||||
spans[0] = sfs[0].getSpan(); if(spans[0] == null) return false;
|
||||
spans[1] = sfs[1].getSpan(); if(spans[1] == null) return false;
|
||||
if(spans[0].getStartOffs() != spans[1].getStartOffs()) return false;
|
||||
return true;
|
||||
}
|
||||
if(l1 < l2) {
|
||||
Span tmp = spans[0];
|
||||
sfs[0] = sfs[0].getNext(); if(sfs[0] == null) return false;
|
||||
spans[0] = sfs[0].getSpan(); if(spans[0] == null) return false;
|
||||
return tmp.isAppendable(spans[0]);
|
||||
} else {
|
||||
Span tmp = spans[1];
|
||||
sfs[1] = sfs[1].getNext(); if(sfs[1] == null) return false;
|
||||
spans[1] = sfs[1].getSpan(); if(spans[1] == null) return false;
|
||||
return tmp.isAppendable(spans[1]);
|
||||
}
|
||||
}
|
||||
|
||||
public void decorate(final FlobSet into, final String path,
|
||||
final ZZCell view) {
|
||||
|
||||
p("Putting beams...");
|
||||
final BeamDecor.Builder bb = new BeamDecor.Builder(into);
|
||||
|
||||
final SpanSet ss = new SpanTree();
|
||||
|
||||
final Hashtable done = new Hashtable();
|
||||
|
||||
final SpanFlob[] sfs = new SpanFlob[2];
|
||||
final Span[] sps = new Span[2];
|
||||
final Span[] sps0 = new Span[2];
|
||||
|
||||
// Starts from the surface, goes deeper.
|
||||
// BeamDecor renders first-put ones last, which is
|
||||
// exactly right for this.
|
||||
|
||||
// XXX WRONG!
|
||||
// ss gets added things so that the span gets
|
||||
// drawn when the deeper one is reached, not earlier.
|
||||
// hmm...
|
||||
into.iterDepth(new FlobSet.DepthIter() {
|
||||
public void act(Flob[] flobs, int start, int n) {
|
||||
bb.startl((n+8)*4, depth);
|
||||
for(int f = start; f<start+n; f++) {
|
||||
Flob cur = flobs[f];
|
||||
if(!(cur instanceof SpanFlob)) continue;
|
||||
SpanFlob sf = (SpanFlob)cur;
|
||||
Span sp = sf.getSpan();
|
||||
p("SF: "+sf+" "+sp);
|
||||
if(sp == null) continue;
|
||||
if(sp.length() == 0) continue;
|
||||
|
||||
Object[] ovs = ss.overlaps(sp);
|
||||
ss.addSpan(sp, sf);
|
||||
p("Objs: "+ovs+" "+ovs.length);
|
||||
if(ovs.length > 0) {
|
||||
p("Obj: "+ovs[0]);
|
||||
} else continue;
|
||||
|
||||
|
||||
for(int i=0; i<ovs.length; i++) {
|
||||
Pair pa = new Pair(sf, ovs[i]);
|
||||
if(done.get(pa) != null)
|
||||
continue;
|
||||
Color c = getSpanColor();
|
||||
|
||||
sfs[0] = sf; sps[0] = sfs[0].getSpan();
|
||||
sfs[1] = (SpanFlob)ovs[i]; sps[1] = sfs[1].getSpan();
|
||||
|
||||
sps0[0] = sps[0]; sps0[1] = sps[1];
|
||||
|
||||
putBeam(bb, sfs, sps, c);
|
||||
done.put(pa, pa);
|
||||
|
||||
while(moveBack(sfs, sps)) {
|
||||
putBeam(bb, sfs, sps, c);
|
||||
done.put(new Pair(sfs[0], sfs[1]), pa);
|
||||
}
|
||||
|
||||
sfs[0] = sf; sps[0] = sps0[0];
|
||||
sfs[1] = (SpanFlob)ovs[i]; sps[1] = sps0[1];
|
||||
|
||||
while(moveForw(sfs, sps)) {
|
||||
putBeam(bb, sfs, sps, c);
|
||||
done.put(new Pair(sfs[0], sfs[1]), pa);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}}, false);
|
||||
|
||||
bb.endl();
|
||||
p("Beams finished.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// vim: set syntax=java :
|
||||
66
Java/flob/SimpleBoxType.java
Normal file
66
Java/flob/SimpleBoxType.java
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
SimpleBoxType.java
|
||||
*
|
||||
* Copyright (c) 1999-2001, Ted Nelson and Tuomas Lukka
|
||||
* Copyright (c) 2001, Benja Fallenstein
|
||||
*
|
||||
* You may use and distribute under the terms of either the GNU Lesser
|
||||
* General Public License, either version 2 of the license or,
|
||||
* at your choice, any later version. Alternatively, you may use and
|
||||
* distribute under the terms of the XPL.
|
||||
*
|
||||
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
|
||||
* the licenses.
|
||||
*
|
||||
* This software 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 README
|
||||
* file for more details.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Written by Tuomas Lukka, BoxType adaption by Benja Fallenstein
|
||||
*/
|
||||
|
||||
package org.gzigzag;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.util.*;
|
||||
|
||||
/** A simple BoxType looking like the old CellBgFlobs.
|
||||
* Draws a filled (possibly with several colors) background rectangle,
|
||||
* surrounded by a rectangle of the current foreground color.
|
||||
*/
|
||||
|
||||
public class SimpleBoxType extends BoxType {
|
||||
public static final String rcsid = "$Id: SimpleBoxType.java,v 1.2 2001/03/18 17:50:16 bfallenstein Exp $";
|
||||
public static final boolean dbg = true;
|
||||
// static final void p(String s) { if(dbg) System.out.println(s); }
|
||||
// static final void pa(String s) { System.out.println(s); }
|
||||
|
||||
public void renderBg(Graphics g, BoxedFlob f, int mx, int my,
|
||||
int md, int mw, int mh) {
|
||||
Color oldfg = g.getColor();
|
||||
|
||||
if(f.solids != null) {
|
||||
for(int i=0; i<f.nsolids; i++) {
|
||||
g.setColor(f.solids[i]);
|
||||
g.fillRect(mx+(mw*i)/f.nsolids, my, mw/f.nsolids+1, mh);
|
||||
}
|
||||
} else {
|
||||
g.setColor(bg);
|
||||
g.fillRect(mx, my, mw, mh);
|
||||
}
|
||||
g.setColor(oldfg);
|
||||
}
|
||||
|
||||
public void renderFrame(Graphics g, BoxedFlob f, int mx, int my,
|
||||
int md, int mw, int mh) {
|
||||
g.drawRect(mx-1, my-1, mw, mh);
|
||||
if(mh >= 14) {
|
||||
g.drawRect(mx-2, my-2, mw+2, mh+2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
109
Java/flob/SimpleFlobConnector.zob
Normal file
109
Java/flob/SimpleFlobConnector.zob
Normal file
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
SimpleFlobConnector.zob
|
||||
*
|
||||
* Copyright (c) 2000, Ted Nelson and Tuomas Lukka
|
||||
*
|
||||
* You may use and distribute under the terms of either the GNU Lesser
|
||||
* General Public License, either version 2 of the license or,
|
||||
* at your choice, any later version. Alternatively, you may use and
|
||||
* distribute under the terms of the XPL.
|
||||
*
|
||||
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
|
||||
* the licenses.
|
||||
*
|
||||
* This software 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 README
|
||||
* file for more details.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Written by Tuomas Lukka
|
||||
*/
|
||||
|
||||
package org.gzigzag;
|
||||
import java.util.*;
|
||||
import java.awt.*;
|
||||
|
||||
/** A simple but powerful raster which uses flob coordinates.
|
||||
* Z is the selection dimension, X and Y are the flob dimension
|
||||
* specifications.
|
||||
*/
|
||||
|
||||
public class SimpleFlobConnector implements FlobDecorator, ZOb {
|
||||
public static final String rcsid = "$Id: SimpleFlobConnector.zob,v 1.9 2000/09/19 10:31:59 ajk Exp $";
|
||||
public static boolean dbg = false;
|
||||
static final void p(String s) { if(dbg) System.out.println(s); }
|
||||
static final void pa(String s) { System.out.println(s); }
|
||||
|
||||
STRUCTPARAMS {
|
||||
|
||||
/** Whether the selection dimension is always d.2 or
|
||||
* whether it is the Z dimension.
|
||||
*/
|
||||
boolean selectd2
|
||||
= true;
|
||||
|
||||
/** The path from one handle cell to another.
|
||||
*/
|
||||
ZZPath connection
|
||||
= null;
|
||||
}
|
||||
|
||||
int count;
|
||||
// public SimpleFlobConnector() { }
|
||||
|
||||
// Always middle - to - middle.
|
||||
public void decorate(final FlobSet f, final String path,
|
||||
final ZZCell view) {
|
||||
|
||||
p("SIMPLEFLOBCNNETOR DECORATE!");
|
||||
count = 0;
|
||||
|
||||
final Hashtable done = new Hashtable();
|
||||
|
||||
if(connection == null)
|
||||
throw new ZZError("Must provide value for FlobConnector connection");
|
||||
|
||||
final ConnectionLineDecor.Builder clb = new
|
||||
ConnectionLineDecor.Builder(f, null);
|
||||
clb.startl(100, 1);
|
||||
|
||||
f.iterDepth(new FlobSet.DepthIter() {
|
||||
public void act(Flob[] flobs, int start, int n) {
|
||||
|
||||
for(int i=start; i<start+n; i++) {
|
||||
Flob cur = flobs[i];
|
||||
if(cur.c == null || !cur.flobPath.equals(path))
|
||||
continue;
|
||||
// Now, cur.c is the HANDLE cell. So we know
|
||||
// we can go from it to another handle and
|
||||
// search the flobset for that.
|
||||
|
||||
// XXX Should also show non-existing parents or
|
||||
// children as stubs.. ???
|
||||
|
||||
ZZCell ohandle = connection.readFrom(cur.c, false);
|
||||
if(ohandle == null) continue;
|
||||
|
||||
Flob parent = f.findFlob(path, ohandle);
|
||||
if(parent == null) continue;
|
||||
|
||||
count++;
|
||||
clb.l(parent, 128, 128, cur, 128, 128);
|
||||
|
||||
}
|
||||
}
|
||||
}, true);
|
||||
|
||||
p("SIMPLEFLOBCNNETOR DECORATED "+count);
|
||||
|
||||
clb.endl();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// vim: set syntax=java :
|
||||
|
||||
|
||||
153
Java/flob/SimpleFlobView.zob
Normal file
153
Java/flob/SimpleFlobView.zob
Normal file
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
SimpleFlobRaster.zob
|
||||
*
|
||||
* Copyright (c) 2000, Ted Nelson and Tuomas Lukka
|
||||
*
|
||||
* You may use and distribute under the terms of either the GNU Lesser
|
||||
* General Public License, either version 2 of the license or,
|
||||
* at your choice, any later version. Alternatively, you may use and
|
||||
* distribute under the terms of the XPL.
|
||||
*
|
||||
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
|
||||
* the licenses.
|
||||
*
|
||||
* This software 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 README
|
||||
* file for more details.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Written by Tuomas Lukka
|
||||
*/
|
||||
|
||||
package org.gzigzag;
|
||||
import java.util.*;
|
||||
import java.awt.*;
|
||||
|
||||
/** A simple but powerful raster which uses flob coordinates.
|
||||
* Z is the selection dimension, X and Y are the flob dimension
|
||||
* specifications.
|
||||
*/
|
||||
|
||||
public class SimpleFlobView implements FlobView, ZOb {
|
||||
public static final String rcsid = "$Id$";
|
||||
public static boolean dbg = false;
|
||||
static final void p(String s) { if(dbg) System.out.println(s); }
|
||||
static final void pa(String s) { System.out.println(s); }
|
||||
|
||||
STRUCTPARAMS {
|
||||
|
||||
/** Whether the selection dimension is always d.2 or
|
||||
* whether it is the Z dimension.
|
||||
*/
|
||||
boolean selectd2
|
||||
= true;
|
||||
|
||||
/** The connectors.
|
||||
*/
|
||||
ZOb decorator
|
||||
= null;
|
||||
}
|
||||
|
||||
Component comp;
|
||||
|
||||
static class FlobDim {
|
||||
String name;
|
||||
ZZPath num;
|
||||
ZZPath txt;
|
||||
FlobDim(ZZCell c) {
|
||||
name = c.getText();
|
||||
c = c.s("d.1", 1);
|
||||
if(c==null) throw new ZZError("Invalid flobdim 1");
|
||||
ZZCell ps = c.s("d.2", 1);
|
||||
if(ps==null) throw new ZZError("Invalid flobdim 2");
|
||||
num = ZZPath.createFromStructure1(ps);
|
||||
|
||||
c = c.s("d.1", 1);
|
||||
if(c==null) throw new ZZError("Invalid flobdim 3");
|
||||
ps = c.s("d.2", 1);
|
||||
if(ps==null) throw new ZZError("Invalid flobdim 4");
|
||||
txt = ZZPath.createFromStructure1(ps);
|
||||
}
|
||||
/** Find the zoom record for this dimension and use
|
||||
* it to scale the output coordinates.
|
||||
*/
|
||||
public void findZoom(ZZCell c) {
|
||||
}
|
||||
float ozero = 0, omax = 1;
|
||||
int zero, max;
|
||||
public void setFinalRange(int zero, int max) {
|
||||
this.zero = zero; this.max = max;
|
||||
}
|
||||
public int getNO(ZZCell c) {
|
||||
ZZCell r = num.readFrom(c, false);
|
||||
if(r == null)
|
||||
return -1;
|
||||
float f = Float.valueOf(r.getText()).floatValue();
|
||||
return (int)(((f-ozero)/omax) * max + zero);
|
||||
}
|
||||
}
|
||||
|
||||
public SimpleFlobView() { }
|
||||
|
||||
public void raster(FlobSet into, FlobFactory fact,
|
||||
ZZCell view, String[] dims, ZZCell accursed) {
|
||||
Dimension size = into.getSize();
|
||||
FlobDim x, y;
|
||||
String z = null;
|
||||
ZZCell di = view.s("d.dims", 1);
|
||||
x = new FlobDim(ZZCursorReal.get(di));
|
||||
di = di.s("d.dims", 1);
|
||||
y = new FlobDim(ZZCursorReal.get(di));
|
||||
if(selectd2)
|
||||
z = "d.2";
|
||||
else {
|
||||
di = di.s("d.dims", 1);
|
||||
z = ZZCursorReal.get(di).getText();
|
||||
}
|
||||
|
||||
// Find ZOOM factors
|
||||
ZZCell fz = ZZDefaultSpace.findInheritableParam(view, "FlobZoom");
|
||||
if(fz == null) {
|
||||
fz = view.N("d.2", 1);
|
||||
fz.setText("FlobZoom");
|
||||
fz.N("d.1", 1);
|
||||
}
|
||||
ZZCell zl = fz.s("d.1", 1);
|
||||
|
||||
x.findZoom(zl); x.setFinalRange(0, size.width);
|
||||
y.findZoom(zl); y.setFinalRange(0, size.height);
|
||||
|
||||
// XXX better
|
||||
// This is all our cells.
|
||||
ZZCell[] cells = accursed.h(z, -1).readRank(z, 1, true);
|
||||
|
||||
final int w = 4;
|
||||
final int h = 4;
|
||||
|
||||
// Now get the coordinates.
|
||||
for(int i=0; i<cells.length; i++) {
|
||||
ZZCell c = cells[i].h("d.ref", -1);
|
||||
int xc = x.getNO(c);
|
||||
int yc = y.getNO(c);
|
||||
p("C: "+xc+" "+yc);
|
||||
|
||||
fact.makeFlob(into, cells[i], c,
|
||||
1, xc-w/2, yc-h/2, 1, w, h);
|
||||
}
|
||||
|
||||
if(decorator != null) {
|
||||
if(!(decorator instanceof FlobDecorator))
|
||||
throw new ZZError("FlobDim decorator must be FlobDecorator: "+
|
||||
decorator);
|
||||
((FlobDecorator)decorator).decorate(into, "", view);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// vim: set syntax=java :
|
||||
88
Java/flob/SimpleSceneFlob.java
Normal file
88
Java/flob/SimpleSceneFlob.java
Normal file
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
SceneFlob.java
|
||||
*
|
||||
* Copyright (c) 2000-2001, Ted Nelson and Tuomas Lukka
|
||||
*
|
||||
* You may use and distribute under the terms of either the GNU Lesser
|
||||
* General Public License, either version 2 of the license or,
|
||||
* at your choice, any later version. Alternatively, you may use and
|
||||
* distribute under the terms of the XPL.
|
||||
*
|
||||
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
|
||||
* the licenses.
|
||||
*
|
||||
* This software 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 README
|
||||
* file for more details.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Written by Benja Fallenstein
|
||||
*/
|
||||
package org.gzigzag;
|
||||
import java.util.*;
|
||||
import java.awt.*;
|
||||
|
||||
/** A simple SceneFlob which just draws the given FlobSet, untransformed.
|
||||
*/
|
||||
|
||||
public class SimpleSceneFlob extends SceneFlob {
|
||||
public static final String rcsid = "$Id: SimpleSceneFlob.java,v 1.4 2001/03/18 17:50:16 bfallenstein Exp $";
|
||||
public static final boolean dbg = true;
|
||||
// static final void p(String s) { if(dbg) System.out.println(s); }
|
||||
// static final void pa(String s) { System.out.println(s); }
|
||||
|
||||
public SimpleSceneFlob(int x, int y, int d, int w, int h, ZZCell c, FlobSet sc) {
|
||||
super(x,y,d,w,h,c,sc);
|
||||
}
|
||||
|
||||
/** Transform the given points between the internal and external coordinates.
|
||||
* @param toExt Whether to transform internal to external or vice versa.
|
||||
*/
|
||||
public void transform(double[] srcPtr, double[]dstPts, boolean toExt) {
|
||||
if(toExt)
|
||||
for(int i=0; i<srcPtr.length; i+=2) {
|
||||
dstPts[i] = srcPtr[i]-x;
|
||||
dstPts[i+1] = srcPtr[i+1]-y;
|
||||
}
|
||||
else
|
||||
for(int i=0; i<srcPtr.length; i+=2) {
|
||||
dstPts[i] = srcPtr[i]+x;
|
||||
dstPts[i+1] = srcPtr[i+1]+y;
|
||||
}
|
||||
}
|
||||
|
||||
/** Transform the given point between the internal and external coordinates.
|
||||
* @param toExt Whether to transform internal to external or vice versa.
|
||||
*/
|
||||
public Point transform(Point src, Point dst, boolean toExt) {
|
||||
if(toExt) {
|
||||
dst.x = src.x + x;
|
||||
dst.y = src.y + y;
|
||||
} else {
|
||||
dst.x = src.x - x;
|
||||
dst.y = src.y - y;
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
||||
/** Make this graphics so that we can render into it with the correct
|
||||
* transformation.
|
||||
*/
|
||||
void prepareGraphics(Graphics g, float interpFract) {
|
||||
if(interpFract == 0) {
|
||||
g.translate(x, y);
|
||||
g.setClip(0, 0, w, h);
|
||||
} else {
|
||||
g.translate(
|
||||
(int)(x + interpFract*(interpTo.x-x)),
|
||||
(int)(y + interpFract*(interpTo.y-y))
|
||||
);
|
||||
g.setClip(0, 0,
|
||||
(int)(w + interpFract*(interpTo.w-w)),
|
||||
(int)(h + interpFract*(interpTo.h-h))
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
84
Java/flob/SimpleTextView.zob
Normal file
84
Java/flob/SimpleTextView.zob
Normal file
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
SimpleTextView.zob
|
||||
*
|
||||
* Copyright (c) 1999-2000, Ted Nelson and Tuomas Lukka
|
||||
*
|
||||
* You may use and distribute under the terms of either the GNU Lesser
|
||||
* General Public License, either version 2 of the license or,
|
||||
* at your choice, any later version. Alternatively, you may use and
|
||||
* distribute under the terms of the XPL.
|
||||
*
|
||||
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
|
||||
* the licenses.
|
||||
*
|
||||
* This software 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 README
|
||||
* file for more details.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Written by Benjamin Fallenstein
|
||||
*/
|
||||
|
||||
package org.gzigzag;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.util.*;
|
||||
|
||||
/** A view with the text of a single cell, layoutet as an FText.
|
||||
*/
|
||||
|
||||
public class SimpleTextView implements FlobView, ZOb {
|
||||
public static final String rcsid = "$Id: SimpleTextView.zob,v 1.8 2001/04/02 20:02:51 bfallenstein Exp $";
|
||||
public static boolean dbg = false;
|
||||
static final void p(String s) { if(dbg) System.out.println(s); }
|
||||
static final void pa(String s) { System.out.println(s); }
|
||||
|
||||
STRUCTPARAMS {
|
||||
/** The font to use. */
|
||||
Font font
|
||||
= new Font("SansSerif", Font.PLAIN, 16);
|
||||
|
||||
Color fgcolor
|
||||
= Color.black;
|
||||
|
||||
Color bgcolor
|
||||
= Color.white;
|
||||
|
||||
ZOb ftextlayouter
|
||||
= new FTextLayouter();
|
||||
}
|
||||
|
||||
FontMetrics fm;
|
||||
|
||||
INITIALIZE {
|
||||
fm = FONTMETRICS(font);
|
||||
}
|
||||
|
||||
public void raster(FlobSet into, FlobFactory fact,
|
||||
ZZCell view, String[] dims, ZZCell accursed) {
|
||||
FText ftxt;
|
||||
|
||||
if(bgcolor != null) {
|
||||
ftxt = new FText(new FText.Part[] {
|
||||
new FText.CellPart(accursed, 0, -1, font, fm, bgcolor, fgcolor)
|
||||
});
|
||||
} else {
|
||||
ftxt = new FText(new FText.Part[] {
|
||||
new FText.CursorCellPart(accursed, 0, -1, font, fm, null, fgcolor)
|
||||
});
|
||||
}
|
||||
|
||||
Dimension size = into.getSize();
|
||||
Rectangle rect = new Rectangle(0, 0, size.width, size.height);
|
||||
|
||||
((FTextLayouter)ftextlayouter).place(into, ftxt, rect,
|
||||
0, rect.y+rect.height/2,
|
||||
ZZCursorReal.getVisualTextOffset(view),
|
||||
true, null);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// vim: set syntax=java :
|
||||
58
Java/flob/SpanFlob.java
Normal file
58
Java/flob/SpanFlob.java
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
SpanFlob.java
|
||||
*
|
||||
* Copyright (c) 2000, Ted Nelson and Tuomas Lukka
|
||||
*
|
||||
* You may use and distribute under the terms of either the GNU Lesser
|
||||
* General Public License, either version 2 of the license or,
|
||||
* at your choice, any later version. Alternatively, you may use and
|
||||
* distribute under the terms of the XPL.
|
||||
*
|
||||
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
|
||||
* the licenses.
|
||||
*
|
||||
* This software 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 README
|
||||
* file for more details.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Written by Tuomas Lukka
|
||||
*/
|
||||
package org.gzigzag;
|
||||
import java.util.*;
|
||||
import java.awt.*;
|
||||
|
||||
/** An interface to Flobs that contain a single span.
|
||||
*/
|
||||
|
||||
public interface SpanFlob {
|
||||
String rcsid = "$Id: SpanFlob.java,v 1.5 2000/09/19 10:32:00 ajk Exp $";
|
||||
|
||||
/** The previous and following spanflobs.
|
||||
* These are used for coloring beams: if a beam is being drawn
|
||||
* between vstreams with a lot of the same content, then
|
||||
* the beam should have just one color. These fields enable
|
||||
* the beam drawer to see what the vstream actually is.
|
||||
* These are to be set by the routine that puts the spanflobs in the
|
||||
* flobset.
|
||||
*/
|
||||
SpanFlob getPrev();
|
||||
SpanFlob getNext();
|
||||
void setNext(SpanFlob sf);
|
||||
|
||||
/** The span this flob contains. Might not be the same as
|
||||
* flob.c.getSpan() since this might be just a piece of the cell.
|
||||
* Can return null.
|
||||
*/
|
||||
Span getSpan();
|
||||
|
||||
/** Get the rectangle corresponding to the given span. The offs and end
|
||||
* are given as substring indices to the span returned by getSpan(),
|
||||
* i.e. the characters offs...end-1 are included.
|
||||
*/
|
||||
Rectangle getRectangle(int offs, int end);
|
||||
}
|
||||
|
||||
|
||||
354
Java/flob/SplitCellFlob1.java
Normal file
354
Java/flob/SplitCellFlob1.java
Normal file
@@ -0,0 +1,354 @@
|
||||
/*
|
||||
SplitCellFlob1.java
|
||||
*
|
||||
* Copyright (c) 2000, Ted Nelson and Tuomas Lukka
|
||||
*
|
||||
* You may use and distribute under the terms of either the GNU Lesser
|
||||
* General Public License, either version 2 of the license or,
|
||||
* at your choice, any later version. Alternatively, you may use and
|
||||
* distribute under the terms of the XPL.
|
||||
*
|
||||
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
|
||||
* the licenses.
|
||||
*
|
||||
* This software 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 README
|
||||
* file for more details.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Written by Tuomas Lukka
|
||||
*/
|
||||
|
||||
package org.gzigzag;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.util.*;
|
||||
|
||||
/** A cell, possibly split over a line break.
|
||||
* The broken parts are chained as a linked list.
|
||||
* The cell of this flob is zero if this is not the first in chain.
|
||||
* The text is rendered in the lowest part, just so that all of it
|
||||
* is inside the rectangle.
|
||||
* <p>
|
||||
* XXX Rework the nextPart, parent, next, prev relation!
|
||||
*/
|
||||
|
||||
public class SplitCellFlob1 extends Flob implements SpanFlob {
|
||||
public static final String rcsid = "$Id: SplitCellFlob1.java,v 1.36 2001/04/02 20:21:43 bfallenstein Exp $";
|
||||
public static boolean dbg = false;
|
||||
static final void p(String s) { if(dbg) System.out.println(s); }
|
||||
static final void pa(String s) { System.out.println(s); }
|
||||
|
||||
// The XOR modes.
|
||||
static public final int XOR_NO = 0;
|
||||
static public final int XOR_LINE = 1;
|
||||
static public final int XOR_FRAME = 2;
|
||||
static public final int XOR_SOLID = 3;
|
||||
|
||||
public int xormode = XOR_NO;
|
||||
|
||||
|
||||
/** Whether to clip before drawing the contents of this flob. */
|
||||
public boolean doClip = false;
|
||||
|
||||
/** The next part of this flob. */
|
||||
SplitCellFlob1 nextPart;
|
||||
|
||||
/** The first of this chain. */
|
||||
public SplitCellFlob1 parent;
|
||||
|
||||
/** Index of first character. */
|
||||
public int start;
|
||||
|
||||
/** Number of characters. */
|
||||
public int n;
|
||||
|
||||
/** The text in this flob (substring of c.getText()).
|
||||
* This text is allowed to be modified from outside to allow e.g. for
|
||||
* firstcap. Doing that in any way that does not retain the number
|
||||
* and offsets of characters <em>will</em> screw up beams and many other
|
||||
* things so don't do that ;)
|
||||
*/
|
||||
public String txt;
|
||||
|
||||
public SpanFlob prev, next;
|
||||
public SpanFlob getPrev() { return prev; }
|
||||
public SpanFlob getNext() { return next; }
|
||||
public void setPrev(SpanFlob sf) {
|
||||
prev = sf;
|
||||
if(prev != null) prev.setNext(this);
|
||||
}
|
||||
public void setNext(SpanFlob sf) { next = sf; }
|
||||
|
||||
public Color bg, fg = Color.black;
|
||||
|
||||
Font f;
|
||||
FontMetrics fm;
|
||||
|
||||
/** Set the background of this flob to the color of the topmost cursor. */
|
||||
public void showCursor() {
|
||||
// Only take topmost cursor's color
|
||||
ZZCell curs = getCell().s("d.cursor", 1);
|
||||
if(curs != null) {
|
||||
bg = ZZCursorReal.getColor(curs);
|
||||
if(bg == null)
|
||||
pa("No cursor color!");
|
||||
} else
|
||||
p("No cursors on this cell.");
|
||||
}
|
||||
|
||||
static boolean intostr = false;
|
||||
public String toString() {
|
||||
if(intostr) return super.toString();
|
||||
intostr = true;
|
||||
String ret = super.toString() + "(SPLCF1 bg="+bg+
|
||||
"Parent: ("+parent+") stn: "+start+" "+n+" Txt:'"+txt+"' Cell:"+c
|
||||
+" next: "+nextPart
|
||||
+ " )";
|
||||
intostr = false;
|
||||
return ret;
|
||||
}
|
||||
|
||||
public SplitCellFlob1(int x, int y, int d, int w, int h,
|
||||
ZZCell c, Font f, FontMetrics fm, SplitCellFlob1 parent,
|
||||
int start, int n) {
|
||||
this(x, y, d, w, h, c, f, fm, parent, start, n, null);
|
||||
}
|
||||
|
||||
public SplitCellFlob1(int x, int y, int d, int w, int h,
|
||||
ZZCell c, Font f, FontMetrics fm, SplitCellFlob1 parent,
|
||||
int start, int n, Color bg) {
|
||||
this(x, y, d, w, h, c,
|
||||
c.getText().substring(start, start+n),
|
||||
f, fm, parent, start, n, bg);
|
||||
}
|
||||
|
||||
public SplitCellFlob1(int x, int y, int d, int w, int h,
|
||||
ZZCell c, String txt, Font f, FontMetrics fm, SplitCellFlob1 parent,
|
||||
int start, int n, Color bg) {
|
||||
|
||||
super(x, y, d, w, h, (parent==null ? c : null));
|
||||
p("SplitCellFlob: "+x+" "+y+" "+d+" "+w+" "+h+" "+c+" "+f+" "+
|
||||
fm+" "+parent+" "+start+" "+n+" "+bg);
|
||||
this.f = f; this.fm = fm;
|
||||
if(parent != null) {
|
||||
if(!parent.c.equals(c))
|
||||
throw new ZZError(
|
||||
"Parent and child splitcellflob must have same cell: "+c+
|
||||
" "+parent.c);
|
||||
SplitCellFlob1 prev = parent;
|
||||
while(prev.nextPart != null) prev = prev.nextPart;
|
||||
prev.nextPart = this;
|
||||
this.parent = (parent.parent == null ? parent : parent.parent);
|
||||
}
|
||||
this.start = start; this.n = n;
|
||||
this.txt = txt;
|
||||
this.bg = bg;
|
||||
p("Created splitcellflob: "+this);
|
||||
}
|
||||
|
||||
public SplitCellFlob1(int x, int y, int d, int w, int h,
|
||||
ZZCell c, Font f, FontMetrics fm, SplitCellFlob1 parent,
|
||||
int start, int n, int xormode) {
|
||||
this(x, y, d, w, h, c, f, fm, parent, start, n);
|
||||
}
|
||||
|
||||
public SplitCellFlob1(int x, int y, int d, int w, int h,
|
||||
ZZCell c, Font f, FontMetrics fm, SplitCellFlob1 parent,
|
||||
int start, int n, int xormode, Color bg) {
|
||||
this(x, y, d, w, h, c, f, fm, parent, start, n, bg);
|
||||
this.xormode = xormode;
|
||||
}
|
||||
|
||||
public final ZZCell getCell() {
|
||||
return (parent==null ? c : parent.c);
|
||||
}
|
||||
|
||||
public Span getSpan() {
|
||||
Span sp = getCell().getSpan();
|
||||
if(sp == null) return null;
|
||||
// XXX test for samity
|
||||
return sp.subSpan(start, start+n);
|
||||
}
|
||||
|
||||
public Rectangle getRectangle(Span s) {
|
||||
Span t = getCell().getSpan();
|
||||
int so = (int)(s.getStart().getOffs() - t.getStart().getOffs());
|
||||
int eo = (int)(s.getEnd().getOffs() - t.getStart().getOffs());
|
||||
int sw = fm.stringWidth(txt.substring(0, so));
|
||||
int ew = fm.stringWidth(txt.substring(0, eo));
|
||||
return new Rectangle(x + sw, y, ew-sw, h);
|
||||
}
|
||||
public Rectangle getRectangle(int offs, int end) {
|
||||
int sw = fm.stringWidth(txt.substring(0, offs));
|
||||
int ew = fm.stringWidth(txt.substring(0, end));
|
||||
return new Rectangle(x + sw, y, ew-sw, h);
|
||||
}
|
||||
|
||||
/* Very quick hack to interpolate from and to non-span flobs:
|
||||
* let this read render(g0, x, y, d, w, h) instead of render(g0). Not at
|
||||
* all what the interpolation SHOULD look like, but better than the
|
||||
* nothing we've had before.
|
||||
*/
|
||||
public void render(Graphics g0, int x, int y, int d, int w, int h) {
|
||||
int my = y + h - fm.getDescent();
|
||||
// p("SpliCellFlob drawString: '"+txt+"' "+x+" "+my+" "+fg+" "+bg);
|
||||
|
||||
Graphics g = g0.create();
|
||||
Color bu = g.getColor();
|
||||
if (doClip) g.clipRect(x, y, w, h);
|
||||
g.setFont(f);
|
||||
if(bg != null) {
|
||||
g.setColor(bg);
|
||||
g.fillRect(x, y, w, h);
|
||||
}
|
||||
if(fg != null) g.setColor(fg);
|
||||
else g.setColor(bu);
|
||||
p("SpliCellFlob drawString: '"+txt+"' "+x+" "+my+" "+fg+" "+bg);
|
||||
g.drawString(txt, x, my);
|
||||
|
||||
g.dispose();
|
||||
|
||||
if(nextPart != null)
|
||||
nextPart.render(g0);
|
||||
}
|
||||
|
||||
/** Render an interpolated version.
|
||||
* This is the trickiest routine of this class since we <em>do</em>
|
||||
* want to get the interpolation behaviour just right so that all text
|
||||
* pieces flow to where they are supposed to.
|
||||
*/
|
||||
public void renderInterp(Graphics g0, float fract) {
|
||||
if(interpTo==null) return;
|
||||
if(!(interpTo instanceof SplitCellFlob1)) {
|
||||
super.renderInterp(g0, fract);
|
||||
return;
|
||||
}
|
||||
SplitCellFlob1 t = this;
|
||||
SplitCellFlob1 r = (SplitCellFlob1)interpTo;
|
||||
|
||||
Graphics g = g0.create();
|
||||
Shape clip = g.getClip();
|
||||
if(fg != null) g.setColor(fg);
|
||||
|
||||
// Render the correct fragment of the two and advance.
|
||||
while(t!=null && r!=null) {
|
||||
if(t.start+t.n < r.start) { t = t.nextPart; continue; }
|
||||
if(t.start > r.start+r.n) { r = r.nextPart; continue; }
|
||||
int st = 0;
|
||||
int en = 0;
|
||||
if(t.start < r.start) st = r.start;
|
||||
else st = t.start;
|
||||
if(t.start+t.n < r.start+r.n) en = t.start+t.n;
|
||||
else en = r.start+r.n;
|
||||
int tx = t.getStrX(st);
|
||||
int rx = r.getStrX(st);
|
||||
int x = (int)(tx + (rx-tx)*fract);
|
||||
int ty = t.y + t.h - t.fm.getDescent();
|
||||
int ry = r.y + r.h - r.fm.getDescent();
|
||||
int y = (int)(ty + (ry-ty)*fract);
|
||||
int tw = t.getStrX(en) - tx;
|
||||
int rw = r.getStrX(en) - rx;
|
||||
int w = (int)(tw + (rw-tw)*fract);
|
||||
int realy = (int)(t.y + (r.y-t.y)*fract);
|
||||
if (doClip) {
|
||||
g.clipRect(x, realy, w, t.h);
|
||||
}
|
||||
if(bg != null) {
|
||||
Color col = g.getColor();
|
||||
g.setColor(bg);
|
||||
g.fillRect(x, realy, tw, t.h);
|
||||
g.setColor(col);
|
||||
}
|
||||
g.setFont(t.f);
|
||||
g.drawString(t.txt.substring(st-t.start, en-t.start), x, y);
|
||||
if (doClip) g.setClip(clip);
|
||||
if(t.start+t.n < r.start+r.n) t = t.nextPart;
|
||||
else r = r.nextPart;
|
||||
}
|
||||
g.dispose();
|
||||
}
|
||||
|
||||
public boolean renderXORLine(Graphics g, int cx, int cy) {
|
||||
ZZCursorVirtual vc = (ZZCursorVirtual)hit(cx, cy);
|
||||
if(vc==null) return false;
|
||||
g.setColor(Color.black);
|
||||
g.setXORMode(Color.white);
|
||||
int xo = fm.stringWidth(txt.substring(0, vc.getOffs()-start));
|
||||
g.drawLine(x+xo, y, x+xo, y+h);
|
||||
return true;
|
||||
}
|
||||
|
||||
public void renderXORFrame(Graphics g, boolean left, boolean right) {
|
||||
// XXX instead of using f.h-1 & f.y+1, just don't create overlapping
|
||||
// XXX SplitCellFlobs any more?
|
||||
g.setColor(Color.black);
|
||||
g.setXORMode(Color.white);
|
||||
SplitCellFlob1 f = parent != null ? parent : this;
|
||||
if(left) g.drawLine(f.x, f.y+1, f.x, f.y+f.h-1);
|
||||
while(true) {
|
||||
g.drawLine(f.x, f.y+1, f.x+f.w, f.y+1);
|
||||
g.drawLine(f.x, f.y+f.h-1, f.x+f.w, f.y+f.h-1);
|
||||
if(f.nextPart != null) f = f.nextPart;
|
||||
else break;
|
||||
}
|
||||
if(right) g.drawLine(f.x+f.w, f.y+1, f.x+f.w, f.y+f.h-1);
|
||||
}
|
||||
|
||||
public void renderXORSolid(Graphics g) {
|
||||
g.setColor(Color.black);
|
||||
g.setXORMode(Color.white);
|
||||
SplitCellFlob1 f = parent != null ? parent : this;
|
||||
for(; f != null; f = f.nextPart) {
|
||||
g.fillRect(f.x, f.y, f.w, f.h);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean renderXOR(Graphics g, int cx, int cy) {
|
||||
if(!insideRect(cx, cy)) return false;
|
||||
if(xormode == XOR_NO) return true; // XXX or false?
|
||||
else if(xormode == XOR_LINE) return renderXORLine(g, cx, cy);
|
||||
else if(xormode == XOR_FRAME) renderXORFrame(g, true, true);
|
||||
else if(xormode == XOR_SOLID) renderXORSolid(g);
|
||||
else throw new ZZError("SplitCellFlob1: Unknown XOR mode");
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Get the x-coordinate of a given letter.
|
||||
* @param ind The index, given as starting from the beginning of the cell.
|
||||
* Must satisfy start <= ind <= start+n
|
||||
*/
|
||||
public int getStrX(int ind) {
|
||||
ind -= start;
|
||||
return x + fm.stringWidth(txt.substring(0,ind));
|
||||
}
|
||||
|
||||
public Object hit(int x, int y) {
|
||||
if(!insideRect(x, y)) return null;
|
||||
if(xormode == XOR_FRAME || xormode == XOR_SOLID)
|
||||
return new ZZCursorVirtual(getCell(), ZZCursorVirtual.NO_OFFSET);
|
||||
int ind = ZZUtil.findStringHit(txt, x-this.x, fm) + start;
|
||||
return new ZZCursorVirtual(getCell(), ind);
|
||||
}
|
||||
|
||||
/** Add a line cursor at the given index into the given flobset.
|
||||
*/
|
||||
public void addCurs(FlobSet into, int ind, Color c) {
|
||||
if(parent != null)
|
||||
parent.addCurs0(into, ind, c);
|
||||
else
|
||||
addCurs0(into, ind, c);
|
||||
}
|
||||
private void addCurs0(FlobSet into, int ind, Color c) {
|
||||
if(ind >= start && ind <= start + n) {
|
||||
int x = getStrX(ind) - 1;
|
||||
into.add(new LineDecor(x, y, x, y+h,
|
||||
c, d));
|
||||
}
|
||||
if(nextPart != null)
|
||||
nextPart.addCurs0(into, ind, c);
|
||||
}
|
||||
|
||||
}
|
||||
78
Java/flob/SplitView.zob
Normal file
78
Java/flob/SplitView.zob
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
SplitView.zob
|
||||
*
|
||||
* You may use and distribute under the terms of either the GNU Lesser
|
||||
* General Public License, either version 2 of the license or,
|
||||
* at your choice, any later version. Alternatively, you may use and
|
||||
* distribute under the terms of the XPL.
|
||||
*
|
||||
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
|
||||
* the licenses.
|
||||
*
|
||||
* This software 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 README
|
||||
* file for more details.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Written by Benjamin Fallenstein
|
||||
*/
|
||||
|
||||
package org.gzigzag;
|
||||
import java.awt.*;
|
||||
|
||||
/** A view that shows the ctrl and data windows in one. */
|
||||
|
||||
public class SplitView implements FlobView, ZOb {
|
||||
public static final String rcsid = "$Id: SplitView.zob,v 1.1 2000/12/26 15:20:42 bfallenstein Exp $";
|
||||
/** Should we print out debugging info? */
|
||||
public static boolean dbg = false;
|
||||
static final void p(String s) { if(dbg) pa(s); }
|
||||
static final void pa(String s) { System.out.println(s); }
|
||||
|
||||
STRUCTPARAMS {}
|
||||
|
||||
public void raster(FlobSet into, FlobFactory fact,
|
||||
ZZCell win, String[] dims, ZZCell accursed) {
|
||||
Dimension size = new Dimension(into.getSize());
|
||||
size.width = size.width / 2;
|
||||
FlobSet set = into.create(size), otherset = into.create(size);
|
||||
|
||||
FlobView view = new VanishingView();
|
||||
view.raster(set, fact, win, dims, accursed);
|
||||
|
||||
boolean isctrl = false;
|
||||
ZZCell otherwin = win.s("d.ctrlview", -1);
|
||||
if(otherwin == null) { otherwin=win.s("d.ctrlview"); isctrl=true; }
|
||||
if(otherwin == null)
|
||||
throw new ZZError("SplitView invoked for a window which is " +
|
||||
"not in a control/data pair!");
|
||||
|
||||
String[] otherdims = ZZDefaultSpace.getDimList(otherwin);
|
||||
ZZCell otheracc = ZZCursorReal.get(otherwin);
|
||||
|
||||
ZZCell c = ZZDefaultSpace.findInheritableParam(otherwin, "View");
|
||||
ZZCell rastname = ZZCursorReal.get(c);
|
||||
|
||||
ZOb frz = ZZDefaultSpace.readZOb(rastname);
|
||||
FlobView otherview = null;
|
||||
if(frz != null && frz instanceof FlobView) {
|
||||
otherview = (FlobView)frz ;
|
||||
} else {
|
||||
System.out.println("getScene: invalid type: "+frz);
|
||||
otherview = new NullView();
|
||||
}
|
||||
|
||||
otherview.raster(otherset, fact, otherwin, otherdims, otheracc);
|
||||
|
||||
if(isctrl) {
|
||||
FlobSet tmp = set;
|
||||
set = otherset;
|
||||
otherset = tmp;
|
||||
}
|
||||
|
||||
into.fetch(otherset, 0, 0, 0);
|
||||
into.fetch(set, size.width, 0, 0);
|
||||
}
|
||||
}
|
||||
208
Java/flob/StdLinks.zob
Normal file
208
Java/flob/StdLinks.zob
Normal file
@@ -0,0 +1,208 @@
|
||||
/*
|
||||
StdLinks.zob
|
||||
*
|
||||
* Copyright (c) 1999-2000, Ted Nelson and Tuomas Lukka
|
||||
*
|
||||
* You may use and distribute under the terms of either the GNU Lesser
|
||||
* General Public License, either version 2 of the license or,
|
||||
* at your choice, any later version. Alternatively, you may use and
|
||||
* distribute under the terms of the XPL.
|
||||
*
|
||||
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
|
||||
* the licenses.
|
||||
*
|
||||
* This software 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 README
|
||||
* file for more details.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Written by Tuomas Lukka
|
||||
*/
|
||||
|
||||
package org.gzigzag;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.util.*;
|
||||
|
||||
public class StdLinks implements FlobDecorator {
|
||||
public static final String rcsid = "$Id: StdLinks.zob,v 1.13.10.1 2002/03/07 21:02:41 bfallenstein Exp $";
|
||||
public static boolean dbg = false;
|
||||
static final void p(String s) { if(dbg) System.out.println(s); }
|
||||
static final void pa(String s) { System.out.println(s); }
|
||||
|
||||
STRUCTPARAMS {
|
||||
|
||||
/** Whether to draw badly directioned links as splines.
|
||||
*/
|
||||
boolean splines
|
||||
= true;
|
||||
|
||||
/** Spline radius.
|
||||
*/
|
||||
float splinvec
|
||||
= 50;
|
||||
|
||||
/** Whether the tight-brick mode is used for cells with
|
||||
* non-shown links.
|
||||
*/
|
||||
boolean tightDefault
|
||||
= false;
|
||||
|
||||
/** Whether to draw the links the old way, between corners.
|
||||
*/
|
||||
boolean useCorners
|
||||
= false;
|
||||
|
||||
}
|
||||
|
||||
static int[] xoffs = new int[] {1, 0, 1};
|
||||
static int[] yoffs = new int[] {0, 1, 1};
|
||||
|
||||
public void decorate(final FlobSet f, final String path,
|
||||
final ZZCell view) {
|
||||
final String[] dims = ZZDefaultSpace.getDimList(view);
|
||||
p("DECORATE STDLINKS");
|
||||
// Cells whose connections were done.
|
||||
final Hashtable done = new Hashtable();
|
||||
final Point p1 = new Point(), p2 = new Point();
|
||||
|
||||
final LineDecor.Builder ldb = new LineDecor.Builder(f, null);
|
||||
|
||||
f.iterDepth(new FlobSet.DepthIter() {
|
||||
public void act(Flob[] flobs, int start, int n) {
|
||||
p("STDLINKS ACT "+start+" "+n+" "+flobs[start].d);
|
||||
|
||||
ldb.startl(4*n, flobs[start].d+1);
|
||||
|
||||
for(int i=start; i<start+n; i++) {
|
||||
Flob cur = flobs[i] ;
|
||||
// p("Do flob ");
|
||||
if(cur.c == null || !cur.flobPath.equals(path))
|
||||
continue;
|
||||
p("Do flob.");
|
||||
p(" path: "+cur.flobPath);
|
||||
ZZCell c = cur.c;
|
||||
p(" cell: "+c);
|
||||
for(int d=0; d<dims.length; d++) {
|
||||
if(d >= xoffs.length) break;
|
||||
// p(" Dim: "+dims[d]);
|
||||
|
||||
for(int dir=-1; dir<=1; dir += 2) {
|
||||
ZZCell neigh = c.s(dims[d], dir);
|
||||
p(" Neigh: "+neigh+" "+
|
||||
(neigh!=null?neigh.getText():"")+
|
||||
" "+(neigh==null?
|
||||
"nothing" : done.get(neigh)));
|
||||
if(neigh == null ||
|
||||
done.get(neigh) != null) continue;
|
||||
Flob nfl = f.findFlob(path, neigh);
|
||||
p(" Found: "+nfl);
|
||||
if(nfl != null)
|
||||
p(" ...path: "+nfl.flobPath);
|
||||
// show connections to non-shown cells
|
||||
// XXX: is this tight-brick? if so, this should be
|
||||
// made conditional
|
||||
if(nfl == null) {
|
||||
// XXX UseCorners!!!
|
||||
int xo = xoffs[d];
|
||||
int yo = yoffs[d];
|
||||
int xh = (xo==0 ? 1 : 0);
|
||||
int yh = (yo==0 ? 1 : 0);
|
||||
int df = (dir > 0 ? 1 : 0);
|
||||
int x1 = cur.x + ((2*xo + xh)*cur.w) / 2;
|
||||
int y1 = cur.y + ((2*yo + yh)*cur.h) / 2;
|
||||
int len = 1; // Stub length
|
||||
int wid = 5; // Stub width
|
||||
if (dir < 0) {
|
||||
int cx = cur.x + cur.w / 2;
|
||||
int cy = cur.y + cur.h / 2;
|
||||
x1 = x1 - 2 * (x1 - cx) + dir*xo;
|
||||
y1 = y1 - 2 * (y1 - cy) + dir*yo;
|
||||
}
|
||||
int x2 = x1 + dir * xo * len ;
|
||||
int y2 = y1 + dir * yo * len ;
|
||||
ldb.l(x1, y1, x2, y2);
|
||||
ldb.l(x2+dir*yo*wid/2, y2-dir*xo*wid/2,
|
||||
x2-dir*yo*wid/2, y2+dir*xo*wid/2);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Now, find line coordinates.
|
||||
Flob from=null, to=null;
|
||||
if(dir > 0) {
|
||||
from = cur; to = nfl;
|
||||
} else {
|
||||
from = nfl; to = cur;
|
||||
}
|
||||
if(useCorners) {
|
||||
int xo = xoffs[d];
|
||||
int yo = yoffs[d];
|
||||
int xh = (xo==0 ? 1 : 0);
|
||||
int yh = (yo==0 ? 1 : 0);
|
||||
ldb.l(
|
||||
from.x + (2*xo + xh)*from.w / 2,
|
||||
from.y + (2*yo + yh)*from.h / 2,
|
||||
to.x + (xh)*to.w / 2,
|
||||
to.y + (yh)*to.h / 2
|
||||
);
|
||||
} else {
|
||||
from.getCenter(p1);
|
||||
to.getCenter(p2);
|
||||
// Check the direction.
|
||||
// XXX abstract out!
|
||||
int dx = p2.x - p1.x;
|
||||
int dy = p2.y - p1.y;
|
||||
boolean curve = false;
|
||||
if(splines) {
|
||||
if(d == 0) { // X
|
||||
curve = (dx/(2*dy+1) == 0 || dx < 0);
|
||||
} else if(d == 1) { // Y
|
||||
curve = (dy/(2*dx+1) == 0 || dy < 0);
|
||||
} else if(d == 2) { // Z
|
||||
curve = (
|
||||
dx / (2*dy+1) != 0 ||
|
||||
dy / (2*dx+1) != 0 ||
|
||||
dx < 0 ||
|
||||
dy < 0
|
||||
);
|
||||
}
|
||||
}
|
||||
if(curve) {
|
||||
p("SPLINE! "+d+" "+dx+" "+dy);
|
||||
int aw = from.w + to.w;
|
||||
int ah = from.h + to.h;
|
||||
aw *= 2;
|
||||
ah *= 2;
|
||||
int[] curv = ZZUtil.bulgeCurve(
|
||||
p1.x, p1.y,
|
||||
xoffs[d] * aw, yoffs[d] * ah,
|
||||
p2.x, p2.y, -xoffs[d] * aw,
|
||||
-yoffs[d] * ah,
|
||||
9
|
||||
);
|
||||
for(int p=2; p<curv.length-1; p+=2) {
|
||||
p(curv[p-2]+" "+curv[p-1]);
|
||||
ldb.l(curv[p-2], curv[p-1],
|
||||
curv[p], curv[p+1]);
|
||||
}
|
||||
} else
|
||||
ldb.l(p1.x, p1.y, p2.x, p2.y);
|
||||
}
|
||||
}
|
||||
}
|
||||
done.put(c, c);
|
||||
}
|
||||
|
||||
ldb.endl();
|
||||
}
|
||||
},false);
|
||||
p("DECORATED STDLINKS");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// vim: set syntax=java :
|
||||
73
Java/flob/TextDecor.java
Normal file
73
Java/flob/TextDecor.java
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
TextDecor.java
|
||||
*
|
||||
* You may use and distribute under the terms of either the GNU Lesser
|
||||
* General Public License, either version 2 of the license or,
|
||||
* at your choice, any later version. Alternatively, you may use and
|
||||
* distribute under the terms of the XPL.
|
||||
*
|
||||
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
|
||||
* the licenses.
|
||||
*
|
||||
* This software 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 README
|
||||
* file for more details.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Written by Tuukka Hastrup
|
||||
*/
|
||||
|
||||
package org.gzigzag;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.util.*;
|
||||
|
||||
public class TextDecor extends Renderable {
|
||||
public static final String rcsid = "$Id: TextDecor.java,v 1.4 2000/09/19 10:32:00 ajk Exp $";
|
||||
public static final boolean dbg = true;
|
||||
static final void p(String s) { if(dbg) System.out.println(s); }
|
||||
static final void pa(String s) { System.out.println(s); }
|
||||
|
||||
int[] x;
|
||||
int[] y;
|
||||
String[] txt;
|
||||
Color color;
|
||||
Font font;
|
||||
|
||||
public TextDecor(int x, int y, String txt, Color color, Font font) {
|
||||
this(new int[] {x}, new int[] {y}, new String[] {txt}, color, font);
|
||||
}
|
||||
|
||||
/** Usual constructor.
|
||||
*/
|
||||
public TextDecor(int[] x, int[] y, String[] txt, Color color, Font font) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.txt = txt;
|
||||
this.color = color;
|
||||
this.font = font;
|
||||
}
|
||||
|
||||
public void render(Graphics g) {
|
||||
Color oldc = null;
|
||||
if(color != null) {
|
||||
oldc = g.getColor();
|
||||
g.setColor(color);
|
||||
}
|
||||
Font oldf = null;
|
||||
if(font != null) {
|
||||
oldf = g.getFont();
|
||||
g.setFont(font);
|
||||
}
|
||||
|
||||
for(int i=0;i<txt.length;i++)
|
||||
g.drawString(txt[i], x[i], y[i]);
|
||||
|
||||
if(oldc != null)
|
||||
g.setColor(oldc);
|
||||
if(oldf != null)
|
||||
g.setFont(oldf);
|
||||
}
|
||||
}
|
||||
492
Java/flob/TreeView.zob
Normal file
492
Java/flob/TreeView.zob
Normal file
@@ -0,0 +1,492 @@
|
||||
/*
|
||||
TreeRaster.zob
|
||||
*
|
||||
* You may use and distribute under the terms of either the GNU Lesser
|
||||
* General Public License, either version 2 of the license or,
|
||||
* at your choice, any later version. Alternatively, you may use and
|
||||
* distribute under the terms of the XPL.
|
||||
*
|
||||
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
|
||||
* the licenses.
|
||||
*
|
||||
* This software 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 README
|
||||
* file for more details.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Written by Antti-Juhani Kaijanaho
|
||||
*/
|
||||
|
||||
|
||||
package org.gzigzag;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Vector;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
/** A flobraster showing the ZZ space as a tree-like structure. */
|
||||
public class TreeView implements FlobView, ZOb {
|
||||
public static final String rcsid = "$Id$";
|
||||
/** Should we print out debugging info? */
|
||||
public static boolean dbg = false;
|
||||
static final void p(String s) { if(dbg) pa(s); }
|
||||
static final void pa(String s) { System.out.println("(flob)TreeRaster: " + s); }
|
||||
|
||||
STRUCTPARAMS {
|
||||
|
||||
/** The size factor applied to cells. */
|
||||
float initmul
|
||||
= (float)1.6;
|
||||
|
||||
/** How many recursion levels shall we render (half up, half
|
||||
down depthwise)? */
|
||||
int maxdepth
|
||||
= 4;
|
||||
|
||||
/** The distance between neigbouring cells.
|
||||
*/
|
||||
int[] gap // 2..2
|
||||
= new int[] {3, 6};
|
||||
|
||||
/** The factor of enlargement of cells as they move away
|
||||
depthwise from the accursed cell. Element 0 is
|
||||
horizontal, element 1 is vertical. */
|
||||
float[] shrink
|
||||
= new float[] {(float) 0.7, (float) 0.8};
|
||||
|
||||
/** Should the tree lines be drawn at all? */
|
||||
boolean treelines
|
||||
= true;
|
||||
|
||||
/** Should the tree be shown "depthhorizontal", ie. depth rightwards? */
|
||||
boolean depthhorizontal
|
||||
= false;
|
||||
}
|
||||
|
||||
int recdepth;
|
||||
|
||||
public TreeView() { recdepth = 0; }
|
||||
|
||||
/** A dimension vector in the ZZ space. A dimension vector is
|
||||
immutable. */
|
||||
private static final class DimVector {
|
||||
/** The dimension along which this vector goes. */
|
||||
private String dim;
|
||||
/** The direction (poswards or negwards) along the dimension. */
|
||||
private int dir;
|
||||
|
||||
/** Constructor from dimension and direction. */
|
||||
public DimVector(String dim, int dir) {
|
||||
this.dim = dim;
|
||||
this.dir = dir;
|
||||
if (dir == 0) throw new IllegalArgumentException("Direction must be nonzero.");
|
||||
}
|
||||
|
||||
/** Get the dimension along which this vector goes. */
|
||||
public String getDimension() { return dim; }
|
||||
/** Get the direction along the dimension. */
|
||||
public int getDirection() { return dir; }
|
||||
|
||||
/** Find a cell's successor along this vector. The successor
|
||||
of a cell is defined as the neighbour of that cell on the
|
||||
vector's dimension and direction.
|
||||
|
||||
@param c A cell whose successor is wanted.
|
||||
|
||||
@return Cell which lies along the vector's dimension and
|
||||
direction from the parameter cell*/
|
||||
public ZZCell getCellSuccessor(ZZCell c) {
|
||||
return c.s(dim, dir);
|
||||
}
|
||||
|
||||
|
||||
/** Find a cell's predecessor along this vector. The
|
||||
predecessor of a cell is defined as the neighbour of that
|
||||
cell on the vector's dimension and negated direction. For
|
||||
example, if the vector is "poswards along d.1", then a
|
||||
cell's predecessor is its neighbour negwards along d.1.
|
||||
|
||||
@param c A cell whose predecessor is wanted.
|
||||
|
||||
@return Cell which lies along the vector's dimension and
|
||||
negated direction from the parameter cell*/
|
||||
public ZZCell getCellPredecessor(ZZCell c) {
|
||||
return c.s(dim, -dir);
|
||||
}
|
||||
}
|
||||
|
||||
/** Decider of a cell's size on canvas. */
|
||||
private static final class CellSizeDecider {
|
||||
/** A precomputed prototype size of a cell. This dimension is
|
||||
scaled to reach the size of a cell. */
|
||||
Dimension proto;
|
||||
|
||||
/** Get a cell's size with an enlargement factor. */
|
||||
public Dimension getCellSize(ZZCell c, double frac) {
|
||||
Dimension rv = new Dimension (proto);
|
||||
rv.width *= frac;
|
||||
rv.height *= frac;
|
||||
return rv;
|
||||
}
|
||||
|
||||
/** Creates an instance from a RasterFlobFactory instance.
|
||||
The decisions made by CellSizeDecider will be based on the
|
||||
RasterFlobFactory's decisions. */
|
||||
public CellSizeDecider(FlobFactory fact) {
|
||||
proto = fact.getSize(null, 1);
|
||||
}
|
||||
}
|
||||
|
||||
public class PositionDecider {
|
||||
private Hashtable cellpos = new Hashtable();
|
||||
private Hashtable celldepth = new Hashtable();
|
||||
private Hashtable cellsize = new Hashtable();
|
||||
private Hashtable extracells = new Hashtable();
|
||||
private Hashtable cellchildren = new Hashtable();
|
||||
|
||||
private int canvaswidth;
|
||||
|
||||
private ZZCell accursed;
|
||||
|
||||
/** The current breadth coordinate. */
|
||||
private int currbcoord = 0;
|
||||
|
||||
private DimVector breadth;
|
||||
private DimVector depth;
|
||||
|
||||
private Dimension[] gaps;
|
||||
private Dimension[] csize;
|
||||
private Dimension[] smcsize; // size of "small" cells
|
||||
|
||||
/** Depth coordinates for given depths. */
|
||||
private int[] dcoord;
|
||||
|
||||
private final void py(String s) {
|
||||
p("PositionDecider(" + currdepth + "): " + s);
|
||||
}
|
||||
|
||||
private int currdepth = 0;
|
||||
|
||||
/** Place tree cells.
|
||||
|
||||
@return A vector containing the children of this root.
|
||||
*/
|
||||
public Vector place_tree_cells(ZZCell root) {
|
||||
if (currdepth + 1 >= maxdepth) return new Vector();
|
||||
|
||||
++currdepth;
|
||||
|
||||
Vector rv = new Vector();
|
||||
|
||||
py("start");
|
||||
|
||||
if (root == null) {
|
||||
py("root is null");
|
||||
} else {
|
||||
py("root is " + root.getID());
|
||||
}
|
||||
|
||||
// position a cell not in the tree that lies left from the root
|
||||
ZZCell cell = root == null ? null : breadth.getCellPredecessor(root);
|
||||
if (cell != null && !cellpos.containsKey(cell)) {
|
||||
Dimension s = smcsize[currdepth];
|
||||
Dimension pos = new Dimension();
|
||||
pos.width = currbcoord;
|
||||
pos.height = dcoord[currdepth]
|
||||
+ csize[currdepth].height / 2 - s.height / 2;
|
||||
cellpos.put(cell, pos);
|
||||
celldepth.put(cell, new Integer(maxdepth + 1));
|
||||
cellsize.put(cell, s);
|
||||
extracells.put(cell, cell);
|
||||
currbcoord += s.width + gaps[currdepth].width;
|
||||
}
|
||||
|
||||
if (root != null && cellpos.containsKey(root)) py("root is known");
|
||||
|
||||
int count = 0;
|
||||
for (cell = root;
|
||||
cell != null && (!cellpos.containsKey(cell)
|
||||
|| extracells.containsKey(cell));
|
||||
cell = breadth.getCellSuccessor(cell)) {
|
||||
|
||||
if (extracells.containsKey(cell)) extracells.remove(cell);
|
||||
|
||||
py("cell " + cell.getID());
|
||||
cellpos.put(cell, new Dimension());
|
||||
|
||||
rv.addElement(cell);
|
||||
|
||||
int startbcoord = currbcoord;
|
||||
Vector children = place_tree_cells(depth.getCellSuccessor(cell));
|
||||
int endbcoord = currbcoord;
|
||||
|
||||
cellchildren.put(cell, children);
|
||||
|
||||
Dimension cs = csize[currdepth];
|
||||
|
||||
int dcorr = 0;
|
||||
// contain too many siblings so that
|
||||
// eg. d.cellcreation as breadth does not hang;
|
||||
// however, we must go on until the accursed cell is
|
||||
// with us.
|
||||
if (count > canvaswidth / csize[currdepth].width
|
||||
&& cellpos.containsKey(accursed) && cell != accursed) {
|
||||
cs = smcsize[currdepth];
|
||||
dcorr = csize[currdepth].height / 2 - cs.height / 2;
|
||||
extracells.put(cell, cell);
|
||||
}
|
||||
cellsize.put(cell, cs);
|
||||
|
||||
Dimension cpos = new Dimension((startbcoord + endbcoord - cs.width) / 2,
|
||||
dcoord[currdepth] + dcorr);
|
||||
|
||||
if (cpos.width < startbcoord) cpos.width = startbcoord;
|
||||
|
||||
py("positioning cell " + cell.getID() + " at (" + cpos.width + "," + cpos.height + ")");
|
||||
cellpos.put(cell, cpos);
|
||||
celldepth.put(cell, new Integer(currdepth));
|
||||
if (currbcoord < cpos.width + cs.width + gaps[currdepth].width)
|
||||
currbcoord = cpos.width + cs.width + gaps[currdepth].width;
|
||||
|
||||
// position a cell not in the tree that lies up from the root
|
||||
ZZCell up = depth.getCellPredecessor(cell);
|
||||
if (up != null && !cellpos.containsKey(up)) {
|
||||
Dimension s = smcsize[currdepth];
|
||||
Dimension pos = new Dimension();
|
||||
pos.width = cpos.width + csize[currdepth].width / 2 - s.width / 2;
|
||||
pos.height = cpos.height - s.height - gaps[currdepth].width / 2;
|
||||
cellpos.put(up, pos);
|
||||
celldepth.put(up, new Integer(maxdepth + 1));
|
||||
cellsize.put(up, s);
|
||||
extracells.put(up, up);
|
||||
}
|
||||
|
||||
if (extracells.containsKey(cell)) break;
|
||||
count++;
|
||||
}
|
||||
py("finish");
|
||||
--currdepth;
|
||||
return rv;
|
||||
}
|
||||
|
||||
public PositionDecider(DimVector breadth, DimVector depth,
|
||||
Dimension fs, FlobFactory fact,
|
||||
ZZCell accursed) {
|
||||
this.breadth = breadth;
|
||||
this.depth = depth;
|
||||
this.canvaswidth = fs.width;
|
||||
|
||||
this.accursed = accursed;
|
||||
|
||||
py("created");
|
||||
|
||||
gaps = new Dimension[maxdepth];
|
||||
csize = new Dimension[maxdepth];
|
||||
smcsize = new Dimension[maxdepth];
|
||||
dcoord = new int[maxdepth];
|
||||
|
||||
gaps[maxdepth/2] = new Dimension(gap[0], gap[1]);
|
||||
csize[maxdepth/2] = new Dimension(fact.getSize(null, initmul));
|
||||
if (depthhorizontal) {
|
||||
int tmp = csize[maxdepth/2].width;
|
||||
csize[maxdepth/2].width = csize[maxdepth/2].height;
|
||||
csize[maxdepth/2].height = tmp;
|
||||
}
|
||||
dcoord[maxdepth/2] = (depthhorizontal ? fs.width : fs.height) / 2;
|
||||
for (int i = maxdepth / 2 - 1; i >= 0; i--) {
|
||||
gaps[i] = new Dimension((int)(gaps[i+1].width * shrink[0]),
|
||||
(int)(gaps[i+1].height * shrink[1]));
|
||||
csize[i] = new Dimension((int)(csize[i+1].width * shrink[0]),
|
||||
(int)(csize[i+1].height * shrink[1]));
|
||||
dcoord[i] = dcoord[i+1] - (csize[i+1].height + gaps[i+1].height);
|
||||
}
|
||||
for (int i = maxdepth / 2 + 1; i < maxdepth; i++) {
|
||||
gaps[i] = gaps[maxdepth - 1 - i];
|
||||
csize[i] = csize[maxdepth - 1 - i];
|
||||
dcoord[i] = dcoord[i-1] + csize[i-1].height + gaps[i-1].height;
|
||||
}
|
||||
for (int i = 0; i < maxdepth; i++) {
|
||||
smcsize[i] = new Dimension(csize[i].width / 4,
|
||||
csize[i].height / 4);
|
||||
}
|
||||
|
||||
}
|
||||
public Enumeration getCells() { return cellpos.keys(); }
|
||||
public Dimension getCellPosition(ZZCell c) {
|
||||
return new Dimension((Dimension)cellpos.get(c));
|
||||
}
|
||||
public int getCellDepth(ZZCell c) {
|
||||
return ((Integer) celldepth.get(c)).intValue();
|
||||
}
|
||||
public Dimension getCellSize(ZZCell c) {
|
||||
return new Dimension((Dimension)cellsize.get(c));
|
||||
}
|
||||
|
||||
public boolean existCell(ZZCell c) {
|
||||
return cellpos.containsKey(c);
|
||||
}
|
||||
|
||||
public Enumeration getCellChildren(ZZCell c) {
|
||||
Object o = cellchildren.get(c);
|
||||
Vector v;
|
||||
if (o == null) v = new Vector(); else v = (Vector)o;
|
||||
return v.elements();
|
||||
}
|
||||
}
|
||||
|
||||
public void raster(FlobSet into, FlobFactory fact,
|
||||
ZZCell view, String[] dims, ZZCell accursed) {
|
||||
|
||||
DimVector breadth = new DimVector(dims[0], 1);
|
||||
DimVector depth = new DimVector(dims[1], 1);
|
||||
|
||||
if (depthhorizontal) {
|
||||
DimVector tmp = breadth;
|
||||
breadth = depth;
|
||||
depth = tmp;
|
||||
}
|
||||
|
||||
p("finding the root cell");
|
||||
ZZCell root;
|
||||
{
|
||||
ZZCell cell = accursed;
|
||||
int count = 0;
|
||||
Hashtable seen = new Hashtable();
|
||||
do {
|
||||
root = cell;
|
||||
seen.put(root, root);
|
||||
cell = depth.getCellPredecessor(root);
|
||||
boolean up = true;
|
||||
if (cell == null) {
|
||||
cell = breadth.getCellPredecessor(root);
|
||||
up = false;
|
||||
}
|
||||
if (cell != null && seen.containsKey(cell)) cell = null;
|
||||
if (cell != null && up) count++;
|
||||
} while (cell != null && count < maxdepth / 2);
|
||||
p("done finding the root cell");
|
||||
}
|
||||
|
||||
PositionDecider pd = new PositionDecider(breadth, depth,
|
||||
into.getSize(),
|
||||
fact, accursed);
|
||||
|
||||
pd.place_tree_cells(root);
|
||||
|
||||
Dimension acpos;
|
||||
if (pd.existCell(accursed)) {
|
||||
acpos = pd.getCellPosition(accursed);
|
||||
} else {
|
||||
pa("FIXME: accursed cell not in modeled tree");
|
||||
acpos = into.getSize();
|
||||
acpos.width /= 2;
|
||||
acpos.height /= 2;
|
||||
}
|
||||
|
||||
int bcorr = acpos.width - (depthhorizontal
|
||||
? into.getSize().height
|
||||
: into.getSize().width) / 2;
|
||||
|
||||
for (Enumeration e = pd.getCells(); e.hasMoreElements();) {
|
||||
ZZCell cell = (ZZCell) e.nextElement();
|
||||
|
||||
Dimension pos = pd.getCellPosition(cell);
|
||||
|
||||
pos.width -= bcorr;
|
||||
|
||||
|
||||
if (depthhorizontal) {
|
||||
int tmp = pos.width;
|
||||
pos.width = pos.height;
|
||||
pos.height = tmp;
|
||||
}
|
||||
|
||||
Dimension cs = pd.getCellSize(cell);
|
||||
|
||||
if (depthhorizontal) {
|
||||
int tmp = cs.width;
|
||||
cs.width = cs.height;
|
||||
cs.height = tmp;
|
||||
}
|
||||
|
||||
int d = pd.getCellDepth(cell);
|
||||
|
||||
fact.makeFlob(into, cell, cell, 1, pos.width, pos.height,
|
||||
d, cs.width, cs.height);
|
||||
|
||||
// draw tree lines
|
||||
if (treelines) {
|
||||
for (Enumeration f = pd.getCellChildren(cell);
|
||||
f.hasMoreElements();) {
|
||||
ZZCell child = (ZZCell) f.nextElement();
|
||||
Dimension cpos = pd.getCellPosition(child);
|
||||
cpos.width -= bcorr;
|
||||
if (depthhorizontal) {
|
||||
int tmp = cpos.width;
|
||||
cpos.width = cpos.height;
|
||||
cpos.height = tmp;
|
||||
}
|
||||
Dimension chs = pd.getCellSize(child);
|
||||
if (depthhorizontal) {
|
||||
int tmp = chs.width;
|
||||
chs.width = chs.height;
|
||||
chs.height = tmp;
|
||||
}
|
||||
if (depthhorizontal) {
|
||||
into.add(new LineDecor(pos.width + cs.width,
|
||||
pos.height + cs.height / 2,
|
||||
cpos.width,
|
||||
cpos.height + cs.height / 2,
|
||||
Color.red,
|
||||
(pd.getCellDepth(child) + d) / 2));
|
||||
} else {
|
||||
into.add(new LineDecor(pos.width + cs.width / 2,
|
||||
pos.height + cs.height,
|
||||
cpos.width + chs.width / 2,
|
||||
cpos.height,
|
||||
Color.red,
|
||||
(pd.getCellDepth(child) + d) / 2));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// XXX This should be a structparam later on.
|
||||
(new StdLinks()).decorate(into, "", view);
|
||||
|
||||
// Do the dimensions. XXX strings or cells?
|
||||
if (true) {
|
||||
Dimension s = fact.getSize(null, 1);
|
||||
|
||||
ZZCell bdim = ZZCursorReal.get(view.s("d.dims", 1));
|
||||
ZZCell ddim = ZZCursorReal.get(view.s("d.dims", 1).s("d.dims", 1));
|
||||
|
||||
if (bdim == null || ddim == null) {
|
||||
throw new ZZError("no dimensions");
|
||||
}
|
||||
|
||||
Flob bfl = fact.makeFlob(into, bdim, bdim, 1, s.width, 0,
|
||||
1, s.width, s.height);
|
||||
Flob dfl = fact.makeFlob(into, ddim, ddim, 1, 0, s.height,
|
||||
1, s.width, s.height);
|
||||
bfl.flobPath = "dim";
|
||||
dfl.flobPath = "dim";
|
||||
|
||||
int wh = s.width / 2;
|
||||
int hh = s.height / 2;
|
||||
|
||||
into.add(new LineDecor(new int[] { wh, hh, wh, s.height,
|
||||
wh, hh, s.width, hh },
|
||||
8, Color.red, 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// vim: set syntax=java :
|
||||
317
Java/flob/VanishingView.zob
Normal file
317
Java/flob/VanishingView.zob
Normal file
@@ -0,0 +1,317 @@
|
||||
/*
|
||||
VanishingView.zob
|
||||
*
|
||||
* Copyright (c) 1999-2000, Ted Nelson and Tuomas Lukka
|
||||
*
|
||||
* You may use and distribute under the terms of either the GNU Lesser
|
||||
* General Public License, either version 2 of the license or,
|
||||
* at your choice, any later version. Alternatively, you may use and
|
||||
* distribute under the terms of the XPL.
|
||||
*
|
||||
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
|
||||
* the licenses.
|
||||
*
|
||||
* This software 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 README
|
||||
* file for more details.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Written by Tuomas Lukka
|
||||
*/
|
||||
|
||||
|
||||
package org.gzigzag;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.util.*;
|
||||
|
||||
/** A reimplementation of the vanishing raster.
|
||||
* Much simpler than the original one since this one does not try
|
||||
* to do the hard rasters as well.
|
||||
*/
|
||||
|
||||
public class VanishingView implements FlobView, ZOb {
|
||||
public static final String rcsid = "$Id: VanishingView.zob,v 1.9 2000/12/11 02:54:44 tjl Exp $";
|
||||
public static boolean dbg = false;
|
||||
static final void p(String s) { if(dbg) System.out.println(s); }
|
||||
static final void pa(String s) { System.out.println(s); }
|
||||
|
||||
// Following are the parameters out of which the constructor
|
||||
// is created.
|
||||
|
||||
STRUCTPARAMS {
|
||||
|
||||
/** The factor to shrink the cells with when moving away from
|
||||
* center.
|
||||
*/
|
||||
float[] shrink // 2..2
|
||||
= new float[] {(float)0.9, (float)0.9};
|
||||
|
||||
/** The factor the center cell is enlarged with from default.
|
||||
*/
|
||||
float[] initmul // 2..2
|
||||
= new float[] {(float)1.6, (float)1.6};
|
||||
|
||||
/** The factor to enlarge the center cell on top of initmul.
|
||||
* This only has an effect on the center cell whereas initmul
|
||||
* affects all cells.
|
||||
*/
|
||||
float[] centermul // 2..2
|
||||
= new float[] {(float)1.0, (float)1.0};
|
||||
|
||||
/** The distance between neighbouring cells.
|
||||
*/
|
||||
int[] gap // 2..2
|
||||
= new int[] {5, 5};
|
||||
|
||||
/** The depth to raster to.
|
||||
*/
|
||||
int depth
|
||||
= 5;
|
||||
|
||||
/** The precedence order of dimensions.
|
||||
*/
|
||||
int[] pref // 2..5
|
||||
= new int[] {0, 1, 2};
|
||||
|
||||
/** Whether to allow cell sizes to vary.
|
||||
*/
|
||||
boolean varsize
|
||||
= false;
|
||||
|
||||
/** Whether alignment around visual flob center is to be used.
|
||||
* If true, halign is ignored.
|
||||
*/
|
||||
boolean centeralign
|
||||
= true;
|
||||
|
||||
/** Distance reverse perspective.
|
||||
*/
|
||||
float revper
|
||||
= (float)1.00;
|
||||
|
||||
/** Horizontal alignment.
|
||||
* 0 = center, -1 = left, 1 = right.
|
||||
*/
|
||||
int halign
|
||||
= 0;
|
||||
}
|
||||
|
||||
// XXX This should be a structparam later on.
|
||||
FlobDecorator linker = new StdLinks();
|
||||
|
||||
|
||||
// Offsets of x and y
|
||||
static int[] xoffs = new int[] {1, 0, 1};
|
||||
static int[] yoffs = new int[] {0, 1, 1};
|
||||
|
||||
|
||||
public void raster(FlobSet into, FlobFactory fact,
|
||||
ZZCell view, String[] dims, ZZCell accursed) {
|
||||
|
||||
Dimension fs = into.getSize();
|
||||
|
||||
// Precalculate sizes and gaps.
|
||||
int[] xgap = new int[depth];
|
||||
int[] ygap = new int[depth];
|
||||
|
||||
int[] xsize = new int[depth+1];
|
||||
int[] ysize = new int[depth+1];
|
||||
float[] sizfact = new float[depth+1];
|
||||
|
||||
float xf = initmul[0];
|
||||
float yf = initmul[1];
|
||||
Dimension d0 = fact.getSize(null, yf);
|
||||
Dimension d = (varsize ? fact.getSize(accursed, yf) : d0);
|
||||
|
||||
xsize[0] = d.width;
|
||||
ysize[0] = d.height;
|
||||
sizfact[0] = yf;
|
||||
float yf0 = yf, xf0=xf;
|
||||
|
||||
for(int i=0; i<depth; i++) {
|
||||
xf *= shrink[0];
|
||||
yf *= shrink[1];
|
||||
xsize[i+1] = (int)(d.width * xf/xf0);
|
||||
ysize[i+1] = (int)(d.height * yf/yf0);
|
||||
sizfact[i+1] = yf;
|
||||
xgap[i] = (int)(gap[0] * xf);
|
||||
ygap[i] = (int)(gap[1] * yf);
|
||||
p("D: "+i+" "+xsize[i+1]+" "+xgap[i]);
|
||||
}
|
||||
|
||||
xsize[0] *= centermul[0];
|
||||
ysize[0] *= centermul[1];
|
||||
|
||||
// flob depth multiplier and offset.
|
||||
// flob depth = d1 + dm*depth
|
||||
int d1 = 1;
|
||||
int dm = 10;
|
||||
int maxd = d1 + dm * depth;
|
||||
|
||||
// The set of cells already put into the flobset
|
||||
Hashtable cellsDone = new Hashtable();
|
||||
|
||||
// The set of flobs for which the given dimensions have been finished
|
||||
// XXX ndims
|
||||
Hashtable []did = new Hashtable[] {
|
||||
new Hashtable(),
|
||||
new Hashtable(),
|
||||
new Hashtable()
|
||||
};
|
||||
|
||||
// The index up to which the cells have been done
|
||||
// for the given dimension
|
||||
// XXX ndims
|
||||
int dimdone[] = new int[] { 0, 0, 0 };
|
||||
|
||||
// The storage of all flobs put.
|
||||
// Relevant only up to min(dimdone).
|
||||
Vector cur = new Vector();
|
||||
|
||||
int cx = fs.width/2-(1+halign)*xsize[0]/2 + halign * d0.width / 2;
|
||||
int cy = fs.height/2-ysize[0]/2;
|
||||
Flob flob = fact.makeFlob(into, accursed, accursed,
|
||||
sizfact[0] , cx, cy, d1, xsize[0], ysize[0]);
|
||||
cur.addElement(flob);
|
||||
cellsDone.put(accursed, accursed);
|
||||
|
||||
// p("Van Start: "+isGrid+" "+shrink[0]+" "+gap[0]+" "+xgap[0]);
|
||||
Flob[] curFlob = new Flob[2];
|
||||
|
||||
Point aligned = new Point();
|
||||
|
||||
for(int dim = 0; dim < pref.length; dim++) {
|
||||
boolean added = false;
|
||||
int start = dimdone[dim];
|
||||
dimdone[dim] = cur.size();
|
||||
|
||||
for(int i=start; i<cur.size(); i++) {
|
||||
curFlob[0] = curFlob[1] = (Flob)cur.elementAt(i);
|
||||
if(curFlob[0].d >= maxd) continue;
|
||||
if(did[dim].get(curFlob[0].c) != null) continue;
|
||||
did[dim].put(curFlob[0].c, curFlob[0].c);
|
||||
|
||||
// Current depth
|
||||
int curd = (curFlob[0].d - d1) / dm;
|
||||
|
||||
ZZIter.NEnum rank = ZZIter.alternate(curFlob[0].c, false, dims[pref[dim]], 1);
|
||||
ZZCell next;
|
||||
while((next = rank.nextCell()) != null) {
|
||||
int curind = (rank.nth() < 0 ? 0 : 1);
|
||||
int dir = curind * 2 - 1;
|
||||
int xdep = (rank.nth() < 0 ? -rank.nth() : rank.nth());
|
||||
Flob f = curFlob[curind];
|
||||
|
||||
if(cellsDone.get(next) != null ||
|
||||
curd + xdep >= depth) {
|
||||
rank.stop();
|
||||
continue;
|
||||
}
|
||||
|
||||
cellsDone.put(next, next);
|
||||
|
||||
if(centeralign) {
|
||||
|
||||
// First, determine alignment.
|
||||
int xalign = dir * xoffs[pref[dim]];
|
||||
int yalign = dir * yoffs[pref[dim]];
|
||||
|
||||
// Then, find alignment point in last cell,
|
||||
// centered on center of screen
|
||||
f.getPoint(aligned, xalign, yalign);
|
||||
|
||||
// Using that, find alignment point
|
||||
// in the next cell.
|
||||
|
||||
aligned.x -= fs.width / 2;
|
||||
aligned.x *= revper;
|
||||
aligned.x += fs.width / 2;
|
||||
|
||||
aligned.y -= fs.height / 2;
|
||||
aligned.y *= revper;
|
||||
aligned.y += fs.height / 2;
|
||||
|
||||
aligned.x += xalign*xgap[curd+xdep-1];
|
||||
aligned.y += yalign*ygap[curd+xdep-1];
|
||||
|
||||
Dimension size = new Dimension(xsize[curd+xdep],
|
||||
ysize[curd+xdep]);
|
||||
f = curFlob[curind] = fact.centerFlob(into, next, next,
|
||||
sizfact[curd+xdep], aligned, -xalign, -yalign,
|
||||
d1 + dm * (curd + xdep), varsize ? null : size);
|
||||
|
||||
} else {
|
||||
|
||||
int x=0, y=0, w=0, h=0;
|
||||
if(varsize) {
|
||||
Dimension dvar = fact.getSize(next, sizfact[curd+xdep]);
|
||||
w = dvar.width;
|
||||
h = dvar.height;
|
||||
} else {
|
||||
w = xsize[curd+xdep];
|
||||
h = ysize[curd+xdep];
|
||||
}
|
||||
|
||||
// A bit tricky due to flob coords being
|
||||
// UL corner.
|
||||
|
||||
// First, find alignment point in last cell,
|
||||
// centered on center of screen
|
||||
int alignedX =
|
||||
f.x + (halign+1)*f.w/2 - fs.width/2;
|
||||
int alignedY =
|
||||
f.y + f.h/2 - fs.height/2;
|
||||
|
||||
// Then, using that, find alignment point
|
||||
// in the next cell.
|
||||
int xof = xoffs[pref[dim]];
|
||||
alignedX += dir * xof * (
|
||||
xgap[curd+xdep-1] + (1-dir*halign) * f.w/2
|
||||
+ (1+dir*halign) * w/2
|
||||
);
|
||||
alignedY += dir * yoffs[pref[dim]] * (
|
||||
ygap[curd+xdep-1] + f.h/2 + h/2
|
||||
);
|
||||
|
||||
// Expand the coordinate system around the
|
||||
// origin
|
||||
alignedX *= revper;
|
||||
alignedY *= revper;
|
||||
|
||||
// Finally, find upper left corner of next cell.
|
||||
x = alignedX - (halign+1)*w/2 + fs.width/2;
|
||||
y = alignedY - h/2 + fs.height/2;
|
||||
|
||||
p("Vanishing: puttig "+next+
|
||||
x+" "+y+" "+w+" "+h);
|
||||
|
||||
f = curFlob[curind] = fact.makeFlob(into, next, next,
|
||||
sizfact[curd+xdep], x, y,
|
||||
d1 + dm * (curd + xdep), w, h);
|
||||
|
||||
}
|
||||
|
||||
cur.addElement(f);
|
||||
did[dim].put(f.c, f.c);
|
||||
added = true;
|
||||
}
|
||||
}
|
||||
// If we added cells, and we're not doing a hard
|
||||
// raster, start doing dimensions all over again.
|
||||
if(added) dim = -1;
|
||||
}
|
||||
|
||||
linker.decorate(into, "", view);
|
||||
|
||||
// Do the dimensions.
|
||||
if(true)
|
||||
ZZUtil.showFlobDims(into, fact, view, 3);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// vim: set syntax=java :
|
||||
73
Java/flob/VobSet.java
Normal file
73
Java/flob/VobSet.java
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
VobSet.java
|
||||
*
|
||||
* Copyright (c) 2000, Ted Nelson and Tuomas Lukka
|
||||
*
|
||||
* You may use and distribute under the terms of either the GNU Lesser
|
||||
* General Public License, either version 2 of the license or,
|
||||
* at your choice, any later version. Alternatively, you may use and
|
||||
* distribute under the terms of the XPL.
|
||||
*
|
||||
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
|
||||
* the licenses.
|
||||
*
|
||||
* This software 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 README
|
||||
* file for more details.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Written by Tuomas Lukka
|
||||
*/
|
||||
package org.gzigzag;
|
||||
import java.util.*;
|
||||
import java.awt.*;
|
||||
|
||||
/** A draft for a new interface to FlobSet.
|
||||
* The point is that this interface can be implemented by several
|
||||
* things and we can make dfferent views interact in interesting
|
||||
* ways.
|
||||
* <p>
|
||||
* A VobSet can be thought of as a window in some ways...
|
||||
*/
|
||||
|
||||
abstract public class VobSet implements ZZScene {
|
||||
public static final String rcsid = "$Id: VobSet.java,v 1.1 2000/12/11 02:54:10 tjl Exp $";
|
||||
|
||||
public static final boolean dbg = true;
|
||||
static final void p(String s) { if(dbg) System.out.println(s); }
|
||||
static final void pa(String s) { System.out.println(s); }
|
||||
|
||||
abstract public Rectangle getBounds();
|
||||
abstract public int getDepth();
|
||||
|
||||
// XXX Make it use ZZDrawing2D to get the bg paint.
|
||||
abstract public Color getBackground();
|
||||
|
||||
abstract public void add(Renderable r);
|
||||
abstract public void add(Flob f);
|
||||
|
||||
// ??? protected void depthColor(Graphics g, int depth) {
|
||||
|
||||
abstract public void dump();
|
||||
|
||||
/** A callback interface for iterating over the Flobs
|
||||
* in a FlobSet in depth order.
|
||||
*/
|
||||
public interface DepthIter {
|
||||
void act(Flob[] flobs, int start, int n);
|
||||
}
|
||||
|
||||
/** Iterate a routine over a blocks of same-depth flobs.
|
||||
*/
|
||||
abstract public void iterDepth(DepthIter di, boolean frontFirst);
|
||||
|
||||
|
||||
|
||||
// XXX Spanset?
|
||||
// abstract public SpanFlob[] findFlobs(Span s);
|
||||
|
||||
// abstract public
|
||||
|
||||
}
|
||||
129
Java/flob/WindowCellView.zob
Normal file
129
Java/flob/WindowCellView.zob
Normal file
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
ClockCellView.zob
|
||||
*
|
||||
* Copyright (c) 2000-2001, Ted Nelson and Tuomas Lukka
|
||||
* Copyright (c) 2001, Benja Fallenstein
|
||||
*
|
||||
* You may use and distribute under the terms of either the GNU Lesser
|
||||
* General Public License, either version 2 of the license or,
|
||||
* at your choice, any later version. Alternatively, you may use and
|
||||
* distribute under the terms of the XPL.
|
||||
*
|
||||
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
|
||||
* the licenses.
|
||||
*
|
||||
* This software 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 README
|
||||
* file for more details.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Written by Benja Fallenstein
|
||||
*/
|
||||
|
||||
package org.gzigzag;
|
||||
import java.util.*;
|
||||
import java.awt.*;
|
||||
|
||||
/** A cell view that shows the contents of a window.
|
||||
* Use this ZOb as the headcell on d.cellview from the window's cursor cell,
|
||||
* and that cell will appear as the window's contents.
|
||||
*/
|
||||
|
||||
public class WindowCellView implements FlobFactory, ZOb {
|
||||
public static final String rcsid = "$Id: WindowCellView.zob,v 1.3 2001/03/18 17:50:16 bfallenstein Exp $";
|
||||
public static boolean dbg = false;
|
||||
private static void p(String s) { if(dbg) ZZLogger.log(s); }
|
||||
private static void pa(String s) { ZZLogger.log(s); }
|
||||
|
||||
STRUCTPARAMS {
|
||||
}
|
||||
|
||||
public Dimension getSize(ZZCell c, float fract) {
|
||||
// XXX use the bounds as specified in the structure
|
||||
return new Dimension((int)(500*fract), (int)(300*fract));
|
||||
}
|
||||
|
||||
public Flob makeFlob(FlobSet into, ZZCell c0, ZZCell handleCell,
|
||||
float fract,
|
||||
int x, int y, int d, int w, int h) {
|
||||
|
||||
FlobSet sc = into.create(new Dimension(w, h));
|
||||
SceneFlob sf = new SimpleSceneFlob(x, y, d, w, h, c0, sc);
|
||||
CellFlobFactory1.addSolidColors(into, sf, sf);
|
||||
into.add(sf);
|
||||
|
||||
if(w+h < 100) return sf;
|
||||
ZZCell view = c0.getRootclone();
|
||||
|
||||
ZZCell c = ZZDefaultSpace.findInheritableParam(view, "View");
|
||||
ZZCell rastname = ZZCursorReal.get(c);
|
||||
|
||||
ZOb frz = ZZDefaultSpace.readZOb(rastname);
|
||||
FlobView fr = null;
|
||||
if(frz != null && frz instanceof FlobView) {
|
||||
fr = (FlobView)frz ;
|
||||
} else {
|
||||
System.out.println("getScene: invalid type: "+frz);
|
||||
fr = new NullView();
|
||||
}
|
||||
// XXX Signal error
|
||||
|
||||
c = ZZDefaultSpace.findInheritableParam(view, "CellView");
|
||||
|
||||
FlobFactory rff = null;
|
||||
if(c != null) {
|
||||
ZZCell cfact = ZZCursorReal.get(c);
|
||||
|
||||
ZOb ffzob = ZZDefaultSpace.readZOb(cfact);
|
||||
rff = (FlobFactory) ffzob;
|
||||
}
|
||||
|
||||
p("WindowCellView: prepare view");
|
||||
fr.raster(sc, rff, view, ZZDefaultSpace.getDimList(view),
|
||||
ZZCursorReal.get(view));
|
||||
p("WindowCellView: view prepared");
|
||||
|
||||
if(rff != null) {
|
||||
Flob rn = rff.placeFlob(sc, rastname, rastname, (float)1.5, w, 0, 1, 1, 0);
|
||||
rn.flobPath="rastname";
|
||||
}
|
||||
|
||||
return sf;
|
||||
}
|
||||
|
||||
public Flob placeFlob(FlobSet into, ZZCell c, ZZCell handleCell,
|
||||
float fract,
|
||||
int x, int y, int depth,
|
||||
float xfract, float yfract) {
|
||||
Dimension d = getSize(c, fract);
|
||||
return makeFlob(into, c, handleCell, fract,
|
||||
(int)(x-xfract*d.width),
|
||||
(int)(y-yfract*d.height),
|
||||
depth, d.width, d.height);
|
||||
}
|
||||
|
||||
public Flob centerFlob(FlobSet into, ZZCell c, ZZCell handleCell,
|
||||
float fract, Point p, int xalign, int yalign,
|
||||
int depth, Dimension d) {
|
||||
if(d == null) d = getSize(c, fract);
|
||||
int x, y;
|
||||
x = p.x - d.width/2; y = p.y - d.height/2;
|
||||
|
||||
if(xalign < 0) x = p.x;
|
||||
if(xalign > 0) x = p.x - d.width;
|
||||
if(yalign < 0) y = p.y;
|
||||
if(yalign > 0) y = p.y - d.height;
|
||||
p("centerFlob "+p+" "+d+" at "+x+" "+y+" align "+xalign+" "+yalign);
|
||||
return makeFlob(into, c, handleCell, fract, x, y,
|
||||
depth, d.width, d.height);
|
||||
}
|
||||
public Flob centerFlob(FlobSet into, ZZCell c, ZZCell handleCell,
|
||||
float fract, Point p, int xalign, int yalign, int depth) {
|
||||
return centerFlob(into, c, handleCell, fract, p, xalign, yalign,
|
||||
depth, null);
|
||||
}
|
||||
}
|
||||
|
||||
// vim: set syntax=java :
|
||||
Reference in New Issue
Block a user