created mirror

This commit is contained in:
whatever
2026-09-14 20:19:29 -04:00
commit 6764738d92
600 changed files with 87187 additions and 0 deletions

19
Modules/README Normal file
View File

@@ -0,0 +1,19 @@
Modules
=======
This directory contains various modules that depend on things
we don't want the main Java code to depend so that compilation
remains reasonably simple.
So the rule is: the Java code in the main package MAY NOT REFER TO
THESE CLASSES EXPLICITLY. Referrals are to happen through Class.forName()
with the name obtained through the structure. All code in the main package
should work without these modules.
Currently, the modules are
mbox/ -- convert an mbox into a String stream and ZZCell structure.
applet/ -- zigzag within the browser ! Actually this isn't a module,
in a sense that ZZApplet doesn't conform to ZZModule
interface. ZZApplet is located here because it requires
XML module to work.

View File

@@ -0,0 +1,42 @@
/*
ZZApplet.java
*
* Copyright (c) 1999-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 Benjamin Fallenstein
*/
package org.gzigzag;
import java.awt.*;
import java.applet.*;
import java.io.*;
import java.util.*;
public class ZZApplet extends Applet {
public static final String rcsid = "$Id: ZZApplet.java,v 1.11 2001/04/01 15:46:49 tjl Exp $";
public void init() {
// XXX Should really store the data somewhere. Currently ^S fails.
ZZSpace space = new ZZCacheDimSpace(new DummyStreamSet());
ZZDefaultSpace.create(space.getHomeCell());
setLayout(new BorderLayout());
ZZWindows.init(space,this);
ZZObsTrigger.runObsQueue();
}
}

View File

@@ -0,0 +1,12 @@
<html>
<head>
<title>GZigZag</title>
</head>
<body>
<applet codebase="./" code="org.gzigzag.ZZApplet" width=600 height=400>
Unbelievably cool GZigZag demo.
</applet>
</body>
</html>

View File

@@ -0,0 +1,36 @@
/*
AwtCursor.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 Kimmo Wideroos
*/
package org.gzigzag.module;
import org.gzigzag.*;
import java.util.*;
import java.awt.*;
public class AwtCursor {
Color color;
boolean shared;
public AwtCursor(Color cursorColor, boolean shared) {
color = cursorColor;
this.shared = shared;
}
}

176
Modules/awtool/AwtLink.java Normal file
View File

@@ -0,0 +1,176 @@
/* DO NOT EDIT THIS FILE. THIS FILE WAS GENERATED FROM ../Modules/awtool/AwtLink.zob,
* EDIT THAT FILE INSTEAD!
* All changes to this file will be lost.
*/
/*
AwtLink.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 Kimmo Wideroos
*/
package org.gzigzag.module;
import org.gzigzag.*;
import java.awt.*;
import java.util.*;
public class AwtLink extends ZObCellRepr implements ZOb {
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); }
/** UNDOCUMENTED.
* <p>Default value: <PRE> 0.0;</PRE>.
* @structparam 1
*/
public
double x
= 0.0;/** UNDOCUMENTED.
* <p>Default value: <PRE> 0.0;</PRE>.
* @structparam 1
*/
public double y
= 0.0;/** UNDOCUMENTED.
* <p>Default value: <PRE> false;</PRE>.
* @structparam 1
*/
public boolean fixed
= false;
/* AUTOGENERATED! */
static final private int fullmask = 7;
/* AUTOGENERATED! */
public String readParams(ZZCell start) {
int m = 0;
try {
if(start != null)
m = readParams(start, 0);
} catch(Throwable t) {
ZZLogger.exc(t);
} finally {
}
if((m & fullmask) != fullmask) {
// not all parameters present - no problem right now.
}
return "";
}
/* AUTOGENERATED! */
private int readParams(ZZCell start, int mask) {
ZZCell n = start;
while(n != null) {
String s = n.getText();
// Tests autogenerated from members.
if(s.equals("x")) {
mask |= 1;
try {
ZZCell c = n.s("d.1"); s = c.getText(); x = (Double.valueOf(s)).doubleValue();
} catch(Exception e) {
ZZLogger.exc(e);
}
} else
if(s.equals("y")) {
mask |= 2;
try {
ZZCell c = n.s("d.1"); s = c.getText(); y = (Double.valueOf(s)).doubleValue();
} catch(Exception e) {
ZZLogger.exc(e);
}
} else
if(s.equals("fixed")) {
mask |= 4;
try {
ZZCell c = n.s("d.1"); s = c.getText();
if(s.equals("true")) fixed=true;
else if(s.equals("false")) fixed=false;
else { /* XXX ??? */ }
} catch(Exception e) {
ZZLogger.exc(e);
}
} else
{ } // grab that last "else"
ZZCell h = n.h("d.3");
if(h != null && h != n) {
// recurse
mask |= readParams(h, mask);
}
n = n.s("d.2");
}
return mask;
}
public boolean isFixed() { return fixed; }
public void setX(double x) { this.x = x; }
public void setY(double y) { this.y = y; }
public double getX() { return x; }
public double getY() { return y; }
public ZZCell toHeadCell() {
return getCell().h(AwtUtil.d_from, 1).h(AwtUtil.d_clone);
}
public ZZCell fromHeadCell() {
return getCell().h(AwtUtil.d_to).h(AwtUtil.d_clone);
}
public String getZObName() {
return "Link";
}
public String cellRepr(ZZCell start, boolean clone)
{
ZZCell c = start.getOrNewCell("d.1");
c.setText(getZObClassName());
c = c.getOrNewCell("d.1");
c.setText("x");
c.getOrNewCell("d.1").setText(""+getX());
c = c.getOrNewCell("d.2");
c.setText("y");
c.getOrNewCell("d.1").setText(""+getY());
return "";
}
}
// vim: set syntax=java :

View File

@@ -0,0 +1,80 @@
/*
AwtLink.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 Kimmo Wideroos
*/
package org.gzigzag.module;
import org.gzigzag.*;
import java.awt.*;
import java.util.*;
public class AwtLink extends ZObCellRepr implements ZOb {
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 {
double x
= 0.0;
double y
= 0.0;
boolean fixed
= false;
}
public boolean isFixed() { return fixed; }
public void setX(double x) { this.x = x; }
public void setY(double y) { this.y = y; }
public double getX() { return x; }
public double getY() { return y; }
public ZZCell toHeadCell() {
return getCell().h(AwtUtil.d_from, 1).h(AwtUtil.d_clone);
}
public ZZCell fromHeadCell() {
return getCell().h(AwtUtil.d_to).h(AwtUtil.d_clone);
}
public String getZObName() {
return "Link";
}
public String cellRepr(ZZCell start, boolean clone)
{
ZZCell c = start.getOrNewCell("d.1");
c.setText(getZObClassName());
c = c.getOrNewCell("d.1");
c.setText("x");
c.getOrNewCell("d.1").setText(""+getX());
c = c.getOrNewCell("d.2");
c.setText("y");
c.getOrNewCell("d.1").setText(""+getY());
return "";
}
}
// vim: set syntax=java :

View File

@@ -0,0 +1,502 @@
/* DO NOT EDIT THIS FILE. THIS FILE WAS GENERATED FROM ../Modules/awtool/AwtMetrics.zob,
* EDIT THAT FILE INSTEAD!
* All changes to this file will be lost.
*/
/*
AwtMetrics.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 Kimmo Wideroos
*/
package org.gzigzag.module;
import org.gzigzag.*;
import java.util.*;
import java.awt.*;
/** Abstract class for different metrics (in order to get different
* focus+context effects)
*/
public abstract class AwtMetrics extends ZObCellRepr implements ZOb {
public static boolean dbg = true;
static void p(String s) { if(dbg) System.out.println(s); }
static void pa(String s) { System.out.println(s); }
/** UNDOCUMENTED.
* <p>Default value: <PRE> { 400, 400 };</PRE>.
* @structparam 1
*/
public
int[] RealView
= { 400, 400 };/** UNDOCUMENTED.
* <p>Default value: <PRE> { 400, 400 };</PRE>.
* @structparam 1
*/
public int[] VirtualView
= { 400, 400 };/** UNDOCUMENTED.
* <p>Default value: <PRE> { 0.0, 0.0 };</PRE>.
* @structparam 1
*/
public double[] Origo
= { 0.0, 0.0 };/** UNDOCUMENTED.
* <p>Default value: <PRE> { 200, 200 };</PRE>.
* @structparam 1
*/
public int[] FocusOrigo
= { 200, 200 };/** UNDOCUMENTED.
* <p>Default value: <PRE> true;</PRE>.
* @structparam 1
*/
public boolean GridOn
= true;
/* AUTOGENERATED! */
static final private int fullmask = 31;
/* AUTOGENERATED! */
public String readParams(ZZCell start) {
int m = 0;
try {
if(start != null)
m = readParams(start, 0);
} catch(Throwable t) {
ZZLogger.exc(t);
} finally {
}
if((m & fullmask) != fullmask) {
// not all parameters present - no problem right now.
}
return "";
}
/* AUTOGENERATED! */
private int readParams(ZZCell start, int mask) {
ZZCell n = start;
while(n != null) {
String s = n.getText();
// Tests autogenerated from members.
if(s.equals("RealView")) {
mask |= 1;
try {
// count rank
int i=-1;
for(ZZCell c = n; c!=null; c=c.s("d.1")) i++;
// XXX check range
RealView = new int[i];
i=0;
for(ZZCell c = n.s("d.1");
c!=null; c=c.s("d.1")) {
s = c.getText();
RealView[i] = Integer.parseInt(s); ;
i++;
}
} catch(Exception e) {
ZZLogger.exc(e);
}
} else
if(s.equals("VirtualView")) {
mask |= 2;
try {
// count rank
int i=-1;
for(ZZCell c = n; c!=null; c=c.s("d.1")) i++;
// XXX check range
VirtualView = new int[i];
i=0;
for(ZZCell c = n.s("d.1");
c!=null; c=c.s("d.1")) {
s = c.getText();
VirtualView[i] = Integer.parseInt(s); ;
i++;
}
} catch(Exception e) {
ZZLogger.exc(e);
}
} else
if(s.equals("Origo")) {
mask |= 4;
try {
// count rank
int i=-1;
for(ZZCell c = n; c!=null; c=c.s("d.1")) i++;
// XXX check range
Origo = new double[i];
i=0;
for(ZZCell c = n.s("d.1");
c!=null; c=c.s("d.1")) {
s = c.getText();
Origo[i] = (Double.valueOf(s)).doubleValue();;
i++;
}
} catch(Exception e) {
ZZLogger.exc(e);
}
} else
if(s.equals("FocusOrigo")) {
mask |= 8;
try {
// count rank
int i=-1;
for(ZZCell c = n; c!=null; c=c.s("d.1")) i++;
// XXX check range
FocusOrigo = new int[i];
i=0;
for(ZZCell c = n.s("d.1");
c!=null; c=c.s("d.1")) {
s = c.getText();
FocusOrigo[i] = Integer.parseInt(s); ;
i++;
}
} catch(Exception e) {
ZZLogger.exc(e);
}
} else
if(s.equals("GridOn")) {
mask |= 16;
try {
ZZCell c = n.s("d.1"); s = c.getText();
if(s.equals("true")) GridOn=true;
else if(s.equals("false")) GridOn=false;
else { /* XXX ??? */ }
} catch(Exception e) {
ZZLogger.exc(e);
}
} else
{ } // grab that last "else"
ZZCell h = n.h("d.3");
if(h != null && h != n) {
// recurse
mask |= readParams(h, mask);
}
n = n.s("d.2");
}
return mask;
}
static ZZCell FocusedCell = null;
double FocusCoefficient = focusCoefficientMinimum();
abstract double focusCoefficientMinimum();
abstract double focusCoefficientMaximum();
public double[] RealViewd() {
return new double[] { (double)RealView[0], (double)RealView[1] };
}
public double[] RealViewHalfd() {
return new double[] { (double)RealView[0]*0.5, (double)RealView[1]*0.5 };
}
public void setRealView(int x, int y, boolean adjustFocus) {
if(adjustFocus) {
double[] rvd = RealViewd();
double newfox = ((double)(x*FocusOrigo[0]))/rvd[0];
double newfoy = ((double)(y*FocusOrigo[1]))/rvd[1];
setFocusOrigo((int)newfox, (int)newfoy);
}
RealView[0] = x; RealView[1] = y;
}
public void setRealView(Dimension d, boolean adjustFocus) {
setRealView(d.width, d.height, adjustFocus);
}
public double[] VirtualViewd() {
return new double[] { (double)VirtualView[0], (double)VirtualView[1] };
}
public double[] VirtualViewHalfd() {
return new double[] { (double)VirtualView[0]*0.5, (double)VirtualView[1]*0.5 };
}
public void setVirtualView(int x, int y) {
VirtualView[0] = x; VirtualView[1] = y;
}
public void setOrigo(double ox, double oy) {
Origo[0] = ox;
Origo[1] = oy;
}
public void moveOrigo(double dox, double doy) {
Origo[0] += dox;
Origo[1] += doy;
}
public double[] FocusOrigod() {
return new double[] { (double)FocusOrigo[0], (double)FocusOrigo[1] };
}
public void setFocusOrigo(int fox, int foy) {
setFocusOrigo(fox, foy, null);
}
public void setFocusOrigo(int fox, int foy, ZZCell focusCell) {
FocusOrigo[0] = fox;
FocusOrigo[1] = foy;
if(focusCell != null && focusCell == FocusedCell) {
FocusCoefficient += 1.0;
if(FocusCoefficient > focusCoefficientMaximum())
FocusCoefficient = focusCoefficientMaximum();
} else {
FocusCoefficient = focusCoefficientMinimum();
FocusedCell = focusCell;
}
}
public void init(ZZCell start, Dimension rv, Dimension vv,
double ox, double oy) {
setCell(start);
setRealView(rv.width, rv.height, false);
setVirtualView(vv.width, vv.height);
setOrigo(ox, oy);
setFocusOrigo(rv.width>>1, rv.height>>1);
}
public AwtMetrics() { }
public AwtMetrics(ZZCell start, Dimension rv, Dimension vv,
double ox, double oy)
{
init(start, rv, vv, ox, oy);
}
private Point mapToUnfocusedRealView(double x, double y) {
int rx, ry;
double[] vvhd = VirtualViewHalfd(), rvhd = RealViewHalfd();
rx = (int)(( (x-Origo[0]) * vvhd[0]) + rvhd[0]);
ry = (int)(( (y-Origo[1]) * vvhd[1]) + rvhd[1]);
return new Point(rx, ry);
}
/** mapping from 'virtualview' (=modelview, coordinates
* -1.0<x,y<1.0) to 'realview' (coordinates in this.RealView).
* can be used for example in order to gain an illusion of focus+context
* by demagnifying areas near focus. ceturns 'realview' coordinates.
* @param x x-coordinate ranging from -infinity ... infinity
* @param y y-coordinate
*/
public Point mapToRealView(double x, double y) {
Point ufr; // unfocused realview point
ufr = mapToUnfocusedRealView(x, y);
return focusRealView(ufr.x, ufr.y);
}
/** reverse mapping, see 'mapToRealView' */
public double[] mapToVirtualView(int rx, int ry) {
double x, y;
double[] vvhd = VirtualViewHalfd(), rvhd = RealViewHalfd();
Point iCoord = inverseTransform(rx, ry);
x = (((double)iCoord.x - rvhd[0]) / vvhd[0]) + Origo[0];
y = (((double)iCoord.y - rvhd[1]) / vvhd[1]) + Origo[1];
return new double[] { x, y };
}
public Point mapToRealView(double[] coord) {
return mapToRealView(coord[0], coord[1]);
}
public Point focusRealView(int x, int y) {
double xFocus, yFocus, dx, dy;
double[] d;
double[] vvhd = VirtualViewHalfd();
xFocus = (double)(x - FocusOrigo[0]);
yFocus = (double)(y - FocusOrigo[1]);
d = transformAtFocusNbhood(xFocus/vvhd[0], yFocus/vvhd[1]);
return new Point(FocusOrigo[0]+(int)(vvhd[0]*d[0]), FocusOrigo[1]+(int)(vvhd[1]*d[1]));
}
public Point inverseTransform(int x, int y) {
double xFocus, yFocus, dx, dy;
double[] d;
double[] vvhd = VirtualViewHalfd();
xFocus = (double)(x - FocusOrigo[0]);
yFocus = (double)(y - FocusOrigo[1]);
d = inverseTransformAtFocusNbhood(xFocus/vvhd[0], yFocus/vvhd[1]);
return new Point(FocusOrigo[0]+(int)(vvhd[0]*d[0]), FocusOrigo[1]+(int)(vvhd[1]*d[1]));
}
public double[] getVirtualDimension(int x, int y, Dimension dim) {
double s = getInverseScalingValue(x, y);
double[] vvhd = VirtualViewHalfd();
return new double[] {s*(double)dim.width/vvhd[0], s*(double)dim.height/vvhd[1]};
}
public Dimension getRealDimension(double x, double y, double[] dim) {
double s = getScalingValue(x, y);
double[] vvhd = VirtualViewHalfd();
return new Dimension((int)(s*(double)dim[0]*vvhd[0]), (int)(s*(double)dim[1]*vvhd[1]));
}
abstract public double[] transformAtFocusNbhood(double x, double y,
double focusCoeff);
abstract public double[] inverseTransformAtFocusNbhood(double x, double
y, double focusCoeff);
abstract public double transformScalingValue(double s);
public double[] transformAtFocusNbhood(double x, double y) {
return transformAtFocusNbhood(x, y, FocusCoefficient);
}
public double[] inverseTransformAtFocusNbhood(double x, double y) {
return inverseTransformAtFocusNbhood(x, y, FocusCoefficient);
}
public double getScalingValue(double x, double y) {
double d1x, d1y, d2x, d2y, s;
Point ufr, invf; // unfocused realview point, inverse focus point
Point rPoint = mapToRealView(x, y);
d1x = (double)(rPoint.x-FocusOrigo[0]);
d1y = (double)(rPoint.y-FocusOrigo[1]);
ufr = mapToUnfocusedRealView(x, y);
invf = inverseTransform(FocusOrigo[0], FocusOrigo[1]);
d2x = (double)(ufr.x-invf.x);
d2y = (double)(ufr.y-invf.y);
s = Math.sqrt((d1x*d1x + d1y*d1y)/(d2x*d2x + d2y*d2y));
return transformScalingValue(s);
}
public double getInverseScalingValue(int rx, int ry) {
double d1x, d1y, d2x, d2y, s;
Point ufr, invf; // unfocused realview point, inverse focus point
d1x = rx-FocusOrigo[0];
d1y = ry-FocusOrigo[1];
ufr = inverseTransform(rx, ry);
invf = inverseTransform(FocusOrigo[0], FocusOrigo[1]);
d2x = (double)(ufr.x-invf.x);
d2y = (double)(ufr.y-invf.y);
s = Math.sqrt((d2x*d2x + d2y*d2y)/(d1x*d1x + d1y*d1y));
return transformScalingValue(s);
}
public boolean RealViewEquals(Dimension view) {
if(view.width==RealView[0] && view.height==RealView[1])
return true;
return false;
}
/** Write the parameters of this ZOb back in the cellstructure.
* Returns a string describing the errors encountered, or null if
* everything went fine..
* @param c starting cell
* @param clone whether or not to make the new ZOb centralcell a clone
* of the former centralcell (if cells equal, the whole
* issue is trivial).
*/
String cellRepr(ZZCell start, boolean clone) {
ZZCell c2, c = start.getOrNewCell("d.1");
start.setText(getZObName());
c.setText(getZObClassName());
c = c2 = c.getOrNewCell("d.1");
c.setText("RealView");
c = c.getOrNewCell("d.1");
c.setText(""+RealView[0]);
c = c.getOrNewCell("d.1");
c.setText(""+RealView[1]);
c = c2 = c2.getOrNewCell("d.2");
c.setText("VirtualView");
c = c.getOrNewCell("d.1");
c.setText(""+VirtualView[0]);
c = c.getOrNewCell("d.1");
c.setText(""+VirtualView[1]);
c = c2 = c2.getOrNewCell("d.2");
c.setText("Origo");
c = c.getOrNewCell("d.1");
c.setText(""+Origo[0]);
c = c.getOrNewCell("d.1");
c.setText(""+Origo[1]);
c = c2 = c2.getOrNewCell("d.2");
c.setText("FocusOrigo");
c = c.getOrNewCell("d.1");
c.setText(""+FocusOrigo[0]);
c = c.getOrNewCell("d.1");
c.setText(""+FocusOrigo[1]);
c = c2 = c2.getOrNewCell("d.2");
c.setText("GridOn");
c = c.getOrNewCell("d.1");
c.setText(""+GridOn);
return "";
}
}

View File

@@ -0,0 +1,326 @@
/*
AwtMetrics.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 Kimmo Wideroos
*/
package org.gzigzag.module;
import org.gzigzag.*;
import java.util.*;
import java.awt.*;
/** Abstract class for different metrics (in order to get different
* focus+context effects)
*/
public abstract class AwtMetrics extends ZObCellRepr implements ZOb {
public static boolean dbg = true;
static void p(String s) { if(dbg) System.out.println(s); }
static void pa(String s) { System.out.println(s); }
STRUCTPARAMS {
int[] RealView
= { 400, 400 };
int[] VirtualView
= { 400, 400 };
double[] Origo
= { 0.0, 0.0 };
int[] FocusOrigo
= { 200, 200 };
boolean GridOn
= true;
}
static ZZCell FocusedCell = null;
double FocusCoefficient = focusCoefficientMinimum();
abstract double focusCoefficientMinimum();
abstract double focusCoefficientMaximum();
public double[] RealViewd() {
return new double[] { (double)RealView[0], (double)RealView[1] };
}
public double[] RealViewHalfd() {
return new double[] { (double)RealView[0]*0.5, (double)RealView[1]*0.5 };
}
public void setRealView(int x, int y, boolean adjustFocus) {
if(adjustFocus) {
double[] rvd = RealViewd();
double newfox = ((double)(x*FocusOrigo[0]))/rvd[0];
double newfoy = ((double)(y*FocusOrigo[1]))/rvd[1];
setFocusOrigo((int)newfox, (int)newfoy);
}
RealView[0] = x; RealView[1] = y;
}
public void setRealView(Dimension d, boolean adjustFocus) {
setRealView(d.width, d.height, adjustFocus);
}
public double[] VirtualViewd() {
return new double[] { (double)VirtualView[0], (double)VirtualView[1] };
}
public double[] VirtualViewHalfd() {
return new double[] { (double)VirtualView[0]*0.5, (double)VirtualView[1]*0.5 };
}
public void setVirtualView(int x, int y) {
VirtualView[0] = x; VirtualView[1] = y;
}
public void setOrigo(double ox, double oy) {
Origo[0] = ox;
Origo[1] = oy;
}
public void moveOrigo(double dox, double doy) {
Origo[0] += dox;
Origo[1] += doy;
}
public double[] FocusOrigod() {
return new double[] { (double)FocusOrigo[0], (double)FocusOrigo[1] };
}
public void setFocusOrigo(int fox, int foy) {
setFocusOrigo(fox, foy, null);
}
public void setFocusOrigo(int fox, int foy, ZZCell focusCell) {
FocusOrigo[0] = fox;
FocusOrigo[1] = foy;
if(focusCell != null && focusCell == FocusedCell) {
FocusCoefficient += 1.0;
if(FocusCoefficient > focusCoefficientMaximum())
FocusCoefficient = focusCoefficientMaximum();
} else {
FocusCoefficient = focusCoefficientMinimum();
FocusedCell = focusCell;
}
}
public void init(ZZCell start, Dimension rv, Dimension vv,
double ox, double oy) {
setCell(start);
setRealView(rv.width, rv.height, false);
setVirtualView(vv.width, vv.height);
setOrigo(ox, oy);
setFocusOrigo(rv.width>>1, rv.height>>1);
}
public AwtMetrics() { }
public AwtMetrics(ZZCell start, Dimension rv, Dimension vv,
double ox, double oy)
{
init(start, rv, vv, ox, oy);
}
private Point mapToUnfocusedRealView(double x, double y) {
int rx, ry;
double[] vvhd = VirtualViewHalfd(), rvhd = RealViewHalfd();
rx = (int)(( (x-Origo[0]) * vvhd[0]) + rvhd[0]);
ry = (int)(( (y-Origo[1]) * vvhd[1]) + rvhd[1]);
return new Point(rx, ry);
}
/** mapping from 'virtualview' (=modelview, coordinates
* -1.0<x,y<1.0) to 'realview' (coordinates in this.RealView).
* can be used for example in order to gain an illusion of focus+context
* by demagnifying areas near focus. ceturns 'realview' coordinates.
* @param x x-coordinate ranging from -infinity ... infinity
* @param y y-coordinate
*/
public Point mapToRealView(double x, double y) {
Point ufr; // unfocused realview point
ufr = mapToUnfocusedRealView(x, y);
return focusRealView(ufr.x, ufr.y);
}
/** reverse mapping, see 'mapToRealView' */
public double[] mapToVirtualView(int rx, int ry) {
double x, y;
double[] vvhd = VirtualViewHalfd(), rvhd = RealViewHalfd();
Point iCoord = inverseTransform(rx, ry);
x = (((double)iCoord.x - rvhd[0]) / vvhd[0]) + Origo[0];
y = (((double)iCoord.y - rvhd[1]) / vvhd[1]) + Origo[1];
return new double[] { x, y };
}
public Point mapToRealView(double[] coord) {
return mapToRealView(coord[0], coord[1]);
}
public Point focusRealView(int x, int y) {
double xFocus, yFocus, dx, dy;
double[] d;
double[] vvhd = VirtualViewHalfd();
xFocus = (double)(x - FocusOrigo[0]);
yFocus = (double)(y - FocusOrigo[1]);
d = transformAtFocusNbhood(xFocus/vvhd[0], yFocus/vvhd[1]);
return new Point(FocusOrigo[0]+(int)(vvhd[0]*d[0]), FocusOrigo[1]+(int)(vvhd[1]*d[1]));
}
public Point inverseTransform(int x, int y) {
double xFocus, yFocus, dx, dy;
double[] d;
double[] vvhd = VirtualViewHalfd();
xFocus = (double)(x - FocusOrigo[0]);
yFocus = (double)(y - FocusOrigo[1]);
d = inverseTransformAtFocusNbhood(xFocus/vvhd[0], yFocus/vvhd[1]);
return new Point(FocusOrigo[0]+(int)(vvhd[0]*d[0]), FocusOrigo[1]+(int)(vvhd[1]*d[1]));
}
public double[] getVirtualDimension(int x, int y, Dimension dim) {
double s = getInverseScalingValue(x, y);
double[] vvhd = VirtualViewHalfd();
return new double[] {s*(double)dim.width/vvhd[0], s*(double)dim.height/vvhd[1]};
}
public Dimension getRealDimension(double x, double y, double[] dim) {
double s = getScalingValue(x, y);
double[] vvhd = VirtualViewHalfd();
return new Dimension((int)(s*(double)dim[0]*vvhd[0]), (int)(s*(double)dim[1]*vvhd[1]));
}
abstract public double[] transformAtFocusNbhood(double x, double y,
double focusCoeff);
abstract public double[] inverseTransformAtFocusNbhood(double x, double
y, double focusCoeff);
abstract public double transformScalingValue(double s);
public double[] transformAtFocusNbhood(double x, double y) {
return transformAtFocusNbhood(x, y, FocusCoefficient);
}
public double[] inverseTransformAtFocusNbhood(double x, double y) {
return inverseTransformAtFocusNbhood(x, y, FocusCoefficient);
}
public double getScalingValue(double x, double y) {
double d1x, d1y, d2x, d2y, s;
Point ufr, invf; // unfocused realview point, inverse focus point
Point rPoint = mapToRealView(x, y);
d1x = (double)(rPoint.x-FocusOrigo[0]);
d1y = (double)(rPoint.y-FocusOrigo[1]);
ufr = mapToUnfocusedRealView(x, y);
invf = inverseTransform(FocusOrigo[0], FocusOrigo[1]);
d2x = (double)(ufr.x-invf.x);
d2y = (double)(ufr.y-invf.y);
s = Math.sqrt((d1x*d1x + d1y*d1y)/(d2x*d2x + d2y*d2y));
return transformScalingValue(s);
}
public double getInverseScalingValue(int rx, int ry) {
double d1x, d1y, d2x, d2y, s;
Point ufr, invf; // unfocused realview point, inverse focus point
d1x = rx-FocusOrigo[0];
d1y = ry-FocusOrigo[1];
ufr = inverseTransform(rx, ry);
invf = inverseTransform(FocusOrigo[0], FocusOrigo[1]);
d2x = (double)(ufr.x-invf.x);
d2y = (double)(ufr.y-invf.y);
s = Math.sqrt((d2x*d2x + d2y*d2y)/(d1x*d1x + d1y*d1y));
return transformScalingValue(s);
}
public boolean RealViewEquals(Dimension view) {
if(view.width==RealView[0] && view.height==RealView[1])
return true;
return false;
}
/** Write the parameters of this ZOb back in the cellstructure.
* Returns a string describing the errors encountered, or null if
* everything went fine..
* @param c starting cell
* @param clone whether or not to make the new ZOb centralcell a clone
* of the former centralcell (if cells equal, the whole
* issue is trivial).
*/
String cellRepr(ZZCell start, boolean clone) {
ZZCell c2, c = start.getOrNewCell("d.1");
start.setText(getZObName());
c.setText(getZObClassName());
c = c2 = c.getOrNewCell("d.1");
c.setText("RealView");
c = c.getOrNewCell("d.1");
c.setText(""+RealView[0]);
c = c.getOrNewCell("d.1");
c.setText(""+RealView[1]);
c = c2 = c2.getOrNewCell("d.2");
c.setText("VirtualView");
c = c.getOrNewCell("d.1");
c.setText(""+VirtualView[0]);
c = c.getOrNewCell("d.1");
c.setText(""+VirtualView[1]);
c = c2 = c2.getOrNewCell("d.2");
c.setText("Origo");
c = c.getOrNewCell("d.1");
c.setText(""+Origo[0]);
c = c.getOrNewCell("d.1");
c.setText(""+Origo[1]);
c = c2 = c2.getOrNewCell("d.2");
c.setText("FocusOrigo");
c = c.getOrNewCell("d.1");
c.setText(""+FocusOrigo[0]);
c = c.getOrNewCell("d.1");
c.setText(""+FocusOrigo[1]);
c = c2 = c2.getOrNewCell("d.2");
c.setText("GridOn");
c = c.getOrNewCell("d.1");
c.setText(""+GridOn);
return "";
}
}

View File

@@ -0,0 +1,94 @@
/*
AwtMetricsNormal.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 Kimmo Wideroos
*/
package org.gzigzag.module;
import org.gzigzag.*;
import java.util.*;
import java.awt.*;
/** Focus+context metrics1
*/
public class AwtMetricsFC extends AwtMetrics {
public String getZObName() {
return "Focus+Context";
}
public double[] transformAtFocusNbhood(double x, double y, double focusCoeff) {
double dx, dy, x2, y2;
x2 = x*focusCoeff;
y2 = y*focusCoeff;
if(x2<1 && x2>-1) {
dx = x2;
} else {
dx = x2*x2;
dx = x2>0 ? dx : -dx;
}
if(y2<1 && y2>-1) {
dy = y2;
} else {
dy = y2*y2;
dy = y2>0 ? dy : -dy;
}
return new double[] { dx/focusCoeff, dy/focusCoeff };
}
public double[] inverseTransformAtFocusNbhood(double x, double y, double focusCoeff) {
double dx, dy, x2, y2;
x2 = x*focusCoeff;
y2 = y*focusCoeff;
if(x2<1 && x2>-1) {
dx = x2;
} else {
dx = (x2>0) ? Math.sqrt(x2) : -Math.sqrt(-x2);
}
if(y2<1 && y2>-1) {
dy = y2;
} else {
dy = (y2>0) ? Math.sqrt(y2) : -Math.sqrt(-y2);
}
return new double[] { dx/focusCoeff, dy/focusCoeff };
}
public double transformScalingValue(double s) { return 1.0/s; }
public double focusCoefficientMinimum() { return 4.0; }
public double focusCoefficientMaximum() { return 8.0; }
public AwtMetricsFC() { super(); }
public AwtMetricsFC(ZZCell start, Dimension rv, Dimension vv,
double ox, double oy) {
super(start, rv, vv, ox, oy);
}
}

View File

@@ -0,0 +1,94 @@
/*
AwtMetricsFC2.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 Kimmo Wideroos
*/
package org.gzigzag.module;
import org.gzigzag.*;
import java.util.*;
import java.awt.*;
/** Focus+context metrics2
*/
public class AwtMetricsFC2 extends AwtMetrics {
public String getZObName() {
return "Focus+Context (2)";
}
public double[] transformAtFocusNbhood(double x, double y, double focusCoeff) {
double dx, dy, x2, y2;
x2 = x*focusCoeff;
y2 = y*focusCoeff;
if(x2<1 && x2>-1) {
dx = x2;
} else {
dx = (x2>0) ? Math.sqrt(x2) : -Math.sqrt(-x2);
}
if(y2<1 && y2>-1) {
dy = y2;
} else {
dy = (y2>0) ? Math.sqrt(y2) : -Math.sqrt(-y2);
}
return new double[] { dx/focusCoeff, dy/focusCoeff };
}
public double[] inverseTransformAtFocusNbhood(double x, double y, double focusCoeff) {
double dx, dy, x2, y2;
x2 = x*focusCoeff;
y2 = y*focusCoeff;
if(x2<1 && x2>-1) {
dx = x2;
} else {
dx = x2*x2;
dx = x2>0 ? dx : -dx;
}
if(y2<1 && y2>-1) {
dy = y2;
} else {
dy = y2*y2;
dy = y2>0 ? dy : -dy;
}
return new double[] { dx/focusCoeff, dy/focusCoeff };
}
public double transformScalingValue(double s) { return s; }
public double focusCoefficientMinimum() { return 4.0; }
public double focusCoefficientMaximum() { return 8.0; }
public AwtMetricsFC2() { super(); }
public AwtMetricsFC2(ZZCell start, Dimension rv, Dimension vv,
double ox, double oy) {
super(start, rv, vv, ox, oy);
}
}

View File

@@ -0,0 +1,58 @@
/*
AwtMetricsNormal.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 Kimmo Wideroos
*/
package org.gzigzag.module;
import org.gzigzag.*;
import java.util.*;
import java.awt.*;
/** Default metrics: Euclidean, no focus+context (no scaling)
*/
public class AwtMetricsNormal extends AwtMetrics {
public String getZObName() {
return "Normal(Euclidean)";
}
public double[] transformAtFocusNbhood(double x, double y, double focusCoeff) {
return new double[] { x, y };
}
public double[] inverseTransformAtFocusNbhood(double x, double y, double focusCoeff) {
return new double[] { x, y };
}
public double transformScalingValue(double s) { return 1.0; }
public double focusCoefficientMinimum() { return 1.0; }
public double focusCoefficientMaximum() { return 1.0; }
public AwtMetricsNormal() { super(); }
public AwtMetricsNormal(ZZCell start, Dimension rv, Dimension vv,
double ox, double oy) {
super(start, rv, vv, ox, oy);
}
}

View File

@@ -0,0 +1,110 @@
/*
AwtNileView.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.
*
*/
/*
* Nile1View.java written by Tuomas Lukka,
* AwtNileView - localization for Awtool by Kimmo Wideroos
*/
package org.gzigzag.module;
import org.gzigzag.*;
import java.util.*;
import java.awt.*;
import java.io.*;
/** A view for nile streams.
*/
public class AwtNileView extends Nile1View {
public static final String rcsid = "";
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); }
public AwtNileView() {
init__zob();
}
public void awtNileRaster(FlobSet into, ZZCell view, ZZCell accursed,
Rectangle rect) {
int[] offs = new int[1];
LoopDetector ld = new LoopDetector();
ZZCursor selectEnd = null;
ZZCell sele = view.s("d.nile-sel");
if(sele != null) {
selectEnd = ZZCursorVirtual.createFromReal(sele);
}
// Do the center paragraph first.
ZZCell firstpara = Nile2Iter.findStruct(accursed, -1, true);
ZZCell nextpara = Nile2Iter.findStruct(accursed, 1, false);
FText ft = paragraph(firstpara, nextpara, new ZZCursorReal(view),
offs, selectEnd);
Dimension size = new Dimension(rect.width, rect.height);
//Rectangle rect = new Rectangle(0, 0, size.width, size.height);
Rectangle ctr = placeParagraph(into, ft, firstpara, rect,
0, rect.y+rect.height/2,
ZZCursorReal.getVisualTextOffset(view));
// Go into positive direction.
Rectangle r = ctr;
while(nextpara != null) {
ld.detect(nextpara);
ZZCell next = Nile2Iter.findStruct(nextpara, 1, false);
ft = paragraph(nextpara, next, null, null, selectEnd);
r = placeParagraph(into, ft, nextpara, rect,
1, r.y+r.height + paraskip, 0);
nextpara = next;
if(r.y + r.height > size.height) break;
}
// And negative.
r = ctr;
while(true) {
ZZCell prev = firstpara;
firstpara = Nile2Iter.findStruct(firstpara, -1, false);
if(firstpara == null) break;
ld.detect(firstpara);
ft = paragraph(firstpara, prev, null, null, null);
beginningSentence[0] = true;
r = placeParagraph(into, ft, firstpara, rect,
-1, r.y - paraskip, 0);
if(r.y < 0) break;
}
// into.dump();
Flob cursf = into.findFlob(null, accursed);
// p("Cursf: "+cursf);
if(cursf != null)
((SplitCellFlob1)cursf).addCurs(into, ZZCursorReal.getOffs(view),
Color.red);
}
}
// vim: set syntax=java :

212
Modules/awtool/AwtNote.java Normal file
View File

@@ -0,0 +1,212 @@
/* DO NOT EDIT THIS FILE. THIS FILE WAS GENERATED FROM ../Modules/awtool/AwtNote.zob,
* EDIT THAT FILE INSTEAD!
* All changes to this file will be lost.
*/
/*
Awtnote.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 Kimmo Wideroos
*/
package org.gzigzag.module;
import org.gzigzag.*;
import java.awt.*;
import java.util.*;
/** this is for awt content. change 'AwtNote' => 'AwtContent'
*/
public class AwtNote extends ZObCellRepr implements ZOb {
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); }
/** UNDOCUMENTED.
* <p>Default value: <PRE> 0.1;</PRE>.
* @structparam 1
*/
public
double width
= 0.1;/** UNDOCUMENTED.
* <p>Default value: <PRE> 0.07;</PRE>.
* @structparam 1
*/
public double height
= 0.07;
/* AUTOGENERATED! */
static final private int fullmask = 3;
/* AUTOGENERATED! */
public String readParams(ZZCell start) {
int m = 0;
try {
if(start != null)
m = readParams(start, 0);
} catch(Throwable t) {
ZZLogger.exc(t);
} finally {
}
if((m & fullmask) != fullmask) {
// not all parameters present - no problem right now.
}
return "";
}
/* AUTOGENERATED! */
private int readParams(ZZCell start, int mask) {
ZZCell n = start;
while(n != null) {
String s = n.getText();
// Tests autogenerated from members.
if(s.equals("width")) {
mask |= 1;
try {
ZZCell c = n.s("d.1"); s = c.getText(); width = (Double.valueOf(s)).doubleValue();
} catch(Exception e) {
ZZLogger.exc(e);
}
} else
if(s.equals("height")) {
mask |= 2;
try {
ZZCell c = n.s("d.1"); s = c.getText(); height = (Double.valueOf(s)).doubleValue();
} catch(Exception e) {
ZZLogger.exc(e);
}
} else
{ } // grab that last "else"
ZZCell h = n.h("d.3");
if(h != null && h != n) {
// recurse
mask |= readParams(h, mask);
}
n = n.s("d.2");
}
return mask;
}
// category link
private AwtLink cLink = null;
double x = Double.NaN;
double y = Double.NaN;
public void setCell(ZZCell c) {
super.setCell(c);
ZZCell cc, nCategoryCell = AwtUtil.getNoteCellCategory(c);
if(nCategoryCell != null) {
cc = c.s(AwtUtil.d_from, -1);
if(cc.s("d.1") != null)
cLink = (AwtLink)AwtUtil.readZObClone(cc);
else
cLink = new AwtLink();
cLink.setCell(cc);
} else {
cLink = new AwtLink();
}
}
public double getWidth() { return width; }
public double getHeight() { return height; }
public double[] getDimension() { return new double[] { width, height }; }
public void setDimension(double w, double h) {
width = w;
height = h;
}
public AwtLink getCategoryLink() {
return cLink;
}
public void setCategoryLink(AwtLink cl) {
cLink = cl;
}
public void setCoord(double x, double y) {
cLink.setX(x);
cLink.setY(y);
}
public void setX(double x) {
cLink.setX(x);
}
public void setY(double y) {
cLink.setY(y);
}
public double[] getCoord() {
return new double[] { cLink.getX(), cLink.getY() };
}
public double getX() {
return cLink.getX();
}
public double getY() {
return cLink.getY();
}
public String getZObName() {
return "Note";
}
/** method for storing ZOb back to structure.
* @param start quess;)
* @param clone whether or not to make the new central cell a clone of
* this.cell (default is true).
*/
public String cellRepr(ZZCell start, boolean clone)
{
ZZCell c = start.getOrNewCell("d.1");
c.setText(getZObClassName());
c.setText("AwtNote");
c = c.getOrNewCell("d.1");
c.setText("width");
c.getOrNewCell("d.1").setText(""+getWidth());
c = c.getOrNewCell("d.2");
c.setText("height");
c.getOrNewCell("d.1").setText(""+getHeight());
if(clone && !start.equals(getCell())) {
getCell().connect(AwtUtil.d_clone, start);
}
if(cLink.getCell() != null) cLink.cellRepr();
return "";
}
}
// vim: set syntax=java :

135
Modules/awtool/AwtNote.zob Normal file
View File

@@ -0,0 +1,135 @@
/*
Awtnote.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 Kimmo Wideroos
*/
package org.gzigzag.module;
import org.gzigzag.*;
import java.awt.*;
import java.util.*;
/** this is for awt content. change 'AwtNote' => 'AwtContent'
*/
public class AwtNote extends ZObCellRepr implements ZOb {
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 {
double width
= 0.1;
double height
= 0.07;
}
// category link
private AwtLink cLink = null;
double x = Double.NaN;
double y = Double.NaN;
public void setCell(ZZCell c) {
super.setCell(c);
ZZCell cc, nCategoryCell = AwtUtil.getNoteCellCategory(c);
if(nCategoryCell != null) {
cc = c.s(AwtUtil.d_from, -1);
if(cc.s("d.1") != null)
cLink = (AwtLink)AwtUtil.readZObClone(cc);
else
cLink = new AwtLink();
cLink.setCell(cc);
} else {
cLink = new AwtLink();
}
}
public double getWidth() { return width; }
public double getHeight() { return height; }
public double[] getDimension() { return new double[] { width, height }; }
public void setDimension(double w, double h) {
width = w;
height = h;
}
public AwtLink getCategoryLink() {
return cLink;
}
public void setCategoryLink(AwtLink cl) {
cLink = cl;
}
public void setCoord(double x, double y) {
cLink.setX(x);
cLink.setY(y);
}
public void setX(double x) {
cLink.setX(x);
}
public void setY(double y) {
cLink.setY(y);
}
public double[] getCoord() {
return new double[] { cLink.getX(), cLink.getY() };
}
public double getX() {
return cLink.getX();
}
public double getY() {
return cLink.getY();
}
public String getZObName() {
return "Note";
}
/** method for storing ZOb back to structure.
* @param start quess;)
* @param clone whether or not to make the new central cell a clone of
* this.cell (default is true).
*/
public String cellRepr(ZZCell start, boolean clone)
{
ZZCell c = start.getOrNewCell("d.1");
c.setText(getZObClassName());
c.setText("AwtNote");
c = c.getOrNewCell("d.1");
c.setText("width");
c.getOrNewCell("d.1").setText(""+getWidth());
c = c.getOrNewCell("d.2");
c.setText("height");
c.getOrNewCell("d.1").setText(""+getHeight());
if(clone && !start.equals(getCell())) {
getCell().connect(AwtUtil.d_clone, start);
}
if(cLink.getCell() != null) cLink.cellRepr();
return "";
}
}
// vim: set syntax=java :

329
Modules/awtool/AwtUtil.java Normal file
View File

@@ -0,0 +1,329 @@
/*
AwtUtil.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 Kimmo Wideroos
*/
package org.gzigzag.module;
import org.gzigzag.*;
import java.util.*;
import java.awt.*;
/** Some general stuff
*/
public class AwtUtil {
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 static String d_to="d.map-1";
public static String d_from="d.map-2";
public static String d_categories="d.categories";
public static String d_notes="d.notes";
public static String d_awtool="d.awtool";
public static String d_clone="d.clone";
public static ZZCell addDims(ZZCell defaultDimsBegin) {
Hashtable awtDims = new Hashtable();
awtDims.put(d_to, d_to);
awtDims.put(d_from, d_from);
awtDims.put(d_categories, d_categories);
awtDims.put(d_notes, d_notes);
awtDims.put(d_awtool, d_awtool);
String dim;
for(ZZCell c = defaultDimsBegin; c != null; c = c.s("d.2") ) {
dim = c.getText();
if(awtDims.containsKey(dim))
awtDims.remove(dim);
if(c.equals(defaultDimsBegin.s("d.2", -1))) break;
}
for(Enumeration e = awtDims.keys(); e.hasMoreElements(); ) {
dim = (String)e.nextElement();
defaultDimsBegin.N("d.2", -1).setText(dim);
}
return defaultDimsBegin;
}
/** return awt system list roocell
*/
public static ZZCell getAwtSysList(ZZCell vc) {
ZZCell awtc = ZZDefaultSpace.findInheritableParam(vc, "AwtSystemList");
if(awtc == null) return null;
return ZZCursorReal.get(awtc);
}
/** return active metrics
*/
public static AwtMetrics getAwtMetrics(ZZCell awtsyslist) {
ZZCell metr = getCursoredCell(Awtool.c_metrics, awtsyslist);
if(metr==null) {
metr = awtsyslist.findText(d_awtool, 1, "Metrics");
if(metr!=null) metr = metr.s("d.1");
}
if(metr == null) throw new ZZError("Awtool: Couldn't initialize metrics!!");
AwtMetrics M = (AwtMetrics)readZObClone(metr);
M.setCell(metr);
return M;
}
public static ZZCell getCursoredCell(AwtCursor acur, ZZCell viewcellOrAwtsyslist) {
String cursorName = acur.color.toString();
ZZCell awtsyslist, vc, cur=null, cursors;
// scrutinize 'viewcellOrAwtsyslist'
if(viewcellOrAwtsyslist.getRankLength(d_awtool)>1) {
awtsyslist = viewcellOrAwtsyslist;
vc = null;
} else {
vc = viewcellOrAwtsyslist;
awtsyslist = getAwtSysList(vc);
}
// shared cursors belongs to all awtool views
if(!acur.shared) {
cursors = awtsyslist.findText(d_awtool, 1, "Cursors").s("d.1");
cur = cursors.findText("d.2", 1, cursorName);
} else {
ZZCell scursors, win, vcShared;
ZZCell[] wins;
ZZSpace sp = vc.getSpace();
win = ZZDefaultSpace.findOnSystemlist(sp, "Windows", false);
win = win.s("d.1");
wins = AwtUtil.findAll(win, "d.2", 1, "awtool");
if(wins==null) throw new ZZError("Awtool: No awtool window found!!");
for(int i=0; i<wins.length; i++) {
vcShared = wins[i].s("d.1", 2);
scursors = vcShared.findText("d.2", 1, "SharedCursors").s("d.1");
cur = scursors.findText("d.2", 1, cursorName);
if(cur!=null) break;
}
}
if(cur==null) return null;
return ZZCursorReal.get(cur);
}
public static void setCursor(AwtCursor acur, ZZCell c, ZZCell viewcellOrAwtsyslist) {
String cursorName = acur.color.toString();
ZZCell awtsyslist, vc, cur=null, cursors=null;
// scrutinize 'viewcellOrAwtsyslist'
if(viewcellOrAwtsyslist.getRankLength(d_awtool)>1) {
awtsyslist = viewcellOrAwtsyslist;
vc = null;
} else {
vc = viewcellOrAwtsyslist;
awtsyslist = getAwtSysList(vc);
}
// shared cursors belongs to all awtool views
if(!acur.shared) {
cursors = awtsyslist.findText(d_awtool, 1, "Cursors").s("d.1");
cur = cursors.findText("d.2", 1, cursorName);
} else {
ZZCell win, vcShared;
ZZCell[] wins;
ZZSpace sp = vc.getSpace();
win = ZZDefaultSpace.findOnSystemlist(sp, "Windows", false);
win = win.s("d.1");
wins = AwtUtil.findAll(win, "d.2", 1, "awtool");
if(wins==null) throw new ZZError("Awtool: No awtool window found!!");
for(int i=0; i<wins.length; i++) {
vcShared = wins[i].s("d.1", 2);
cursors = vcShared.findText("d.2", 1, "SharedCursors").s("d.1");
cur = cursors.findText("d.2", 1, cursorName);
if(cur!=null) break;
}
}
if(cur == null) {
if(cursors==null) throw new ZZError("Awtool: awt-cursors not initialized properly!!");
cur = cursors.N("d.2");
cur.setText(cursorName);
ZZCursorReal.set(cur, c);
ZZCursorReal.setColor(cur, acur.color);
return;
}
ZZCursorReal.set(cur, c);
}
public static ZZCell[] findAll(ZZCell start, String dim, int dir, String id) {
ZZCell c;
Vector found = new Vector();
if(start.getText().equals(id)) found.addElement(start);
for(c = start.s(dim, dir); (c!=null) && (c!=start); c = c.s(dim, dir) ) {
if(c.getText().equals(id)) found.addElement(c);
}
int i = found.size();
ZZCell[] fc = new ZZCell[i];
for(i-=1; i>=0; i--) {
fc[i] = (ZZCell)found.elementAt(i);
}
return fc;
}
public interface ObjectComparator {
int compare(Object o1, Object o2);
}
public static void quickSort(Vector a, int lo0, int hi0, ObjectComparator c) {
int lo = lo0;
int hi = hi0;
if (lo >= hi)
return;
Object mid = a.elementAt((lo + hi) / 2);
while (lo < hi) {
while (lo<hi && c.compare(a.elementAt(lo), mid) < 0)
lo++;
while (lo<hi && c.compare(a.elementAt(hi), mid) > 0)
hi--;
if (lo < hi) {
Object T = a.elementAt(lo);
a.setElementAt(a.elementAt(hi), lo);
a.setElementAt(T, hi);
lo++;
hi--;
}
}
if (hi < lo) {
int T = hi;
hi = lo;
lo = T;
}
quickSort(a, lo0, lo, c);
quickSort(a, lo == lo0 ? lo+1 : lo, hi0, c);
}
/** Construct and return a ZOb of the given type.
*/
public static ZOb newModuleZOb(String id) {
// XXX Figure out if we can cache something.
// XXX Should ZOb be able to reset? Easier or less easy than
// recreate? At least ZObs should cache...
try {
Class z = Class.forName("org.gzigzag.module."+id);
return (ZOb)Class.forName("org.gzigzag.module."+id).newInstance();
} catch(Exception e) {
ZZLogger.exc(e);
return null;
}
}
/** Construct a ZOb corresponding to a cell and read the params.
* DOES NOT Go to the rootclone, takes the next cell on d.1 as the ZOb's name,
* and takes the NEXT cell on d.1 as the head of the list from which to
* read the structparams.
*/
static public ZOb readZObClone(ZZCell start) {
//ZZCell c = start.h("d.clone", -1).s("d.1", 1);
if(start.s("d.1") == null) start = start.h("d.clone", -1);
ZZCell c = start.s("d.1", 1);
if(c == null)
throw new ZZError("Error reading ZOb from cell "+start.getText());
ZOb z = newModuleZOb(c.getText());
z.readParams(c.s("d.1", 1));
return z;
}
/** return category cell of the note c
*/
static public ZZCell getNoteCellCategory(ZZCell c) {
ZZCell qwerty = c.s(d_from, -1);
if(qwerty == null) return null;
if(qwerty.equals(qwerty.h(d_to, -1))) return null;
qwerty = qwerty.h(d_to, -1);
if(qwerty.getRankLength(d_categories) == 1) return null;
return qwerty;
}
static public AwtNote createNewNote(ZZCell c, double[] ncenter,
double[] ndim) {
AwtNote newNote = new AwtNote();
newNote.setCell(c);
newNote.setCoord(ncenter[0], ncenter[1]);
newNote.setDimension(ndim[0], ndim[1]);
newNote.cellRepr();
return newNote;
}
public void deleteNote(ZZCell nc) {
// should delete ZOb structures ... in future
// ZObCellRepr will have 'deleteZOb' method.
ZZCell hc = nc.h(d_clone);
nc.delete();
if(hc.getRankLength(d_clone)==1) {
hc.delete();
}
}
static public void createNewLink(ZZCell from, ZZCell to) {
ZZCell newLinkCell = from.h(AwtUtil.d_to, 1).N(AwtUtil.d_to, 1);
to.h(AwtUtil.d_from, -1).connect(AwtUtil.d_from, -1, newLinkCell);
AwtLink al = new AwtLink();
al.setCell(newLinkCell);
al.cellRepr();
}
static public void renderGrid(FlobSet into, AwtMetrics M, double x1, double
y1, double x2, double y2, Color color, int density)
{
double[] coord = new double[2], cstart = new double[2], cinc = new double[2],
d = new double[2], dh = new double[2];
Point p1, p2;
int i, j, a, b;
cstart[0] = (x1 < x2) ? x1 : x2;
cstart[1] = (y1 < y2) ? y1 : x2;
cinc[0] = Math.abs((x2-x1) / ((double)density + 1.0));
cinc[1] = Math.abs((y2-y1) / ((double)density + 1.0));
d[0] = cinc[0] / 5.0;
d[1] = cinc[1] / 5.0;
dh[0] = d[0]/2.0;
dh[1] = d[1]/2.0;
for(a=0; a<2; a++) {
b = (a==0) ? 1 : 0;
coord[a] = cstart[a];
for(i=0; i<=density+1; i++) {
coord[b] = cstart[b]+dh[b]/2.0;
for(j=1; j<=(density+1)*5; j++) {
p1 = M.mapToRealView(coord);
coord[b] += dh[b];
p2 = M.mapToRealView(coord);
coord[b] += dh[b];
into.add(new LineDecor(p1.x, p1.y, p2.x, p2.y, color, 2));
}
coord[a] += cinc[a];
}
}
}
}

View File

@@ -0,0 +1,341 @@
/*
AwtView1.zob
*
* Copyright (c) 2000-2001 Ted Nelson and Tuomas Lukka
* Copyright (c) 2000-2001 Kimmo Wideroos
*
* 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 Kimmo Wideroos
*/
/** View for a(ssociative) writing tool
*/
package org.gzigzag.module;
import org.gzigzag.*;
import java.util.*;
import java.awt.*;
//import java.lang.reflect.*;
public class AwtView1 extends Awtool {
static AwtNileView awtNile = new AwtNileView();
class AwtBgFlob extends CellBgFlob {
public AwtBgFlob(int x, int y, int d, int w, int h, ZZCell c) {
super(x, y, d, w, h, c);
}
public void render(Graphics g, int mx, int my, int md, int mw, int mh) {
Color[] solids = getSolidColors();
int nsolids = 0;
if(solids!=null) nsolids = solids.length;
Color oldfg = g.getColor();
Shape oldclip = g.getClip();
g.clipRect(mx, my, mw, mh);
if(solids != null) {
int iq=0, id=0;
for(int i=0; i<nsolids-1; i++) {
g.setColor(solids[i]);
if(mw-iq-5>0 && mh-iq-5>0) {
g.drawRect(mx+id+1, my+id+1, mw-iq-3, mh-iq-3);
g.drawRect(mx+id+2, my+id+2, mw-iq-5, mh-iq-5);
id += 2;
iq += 4;
}
g.setColor(bg);
g.fillRect(mx+id+1, my+id+1, mw-iq-3, mh-iq-3);
//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???
g.drawRect(mx, my, mw-1, mh-1);
g.setClip(oldclip);
}
}
class AwtLinkFlob extends CellBgFlob {
Point from, to;
AwtLinkFlob(Point from, Point to, ZZCell c) {
super((from.x+to.x)>>1, (from.y+to.y)>>1, Math.abs(from.x-to.x),
Math.abs(from.y-to.y), 2, c);
this.from = from;
this.to = to;
//super((from.x+to.x)>>1, (from.y+to.y)>>1, w, h, 2, c);
}
public void render(Graphics g, int mx, int my, int md,
int mw, int mh) {
Color[] solids = getSolidColors();
int nsolids = 0;
if(solids!=null) nsolids = solids.length;
Color oldfg = g.getColor();
//Shape oldclip = g.getClip();
// XXX save font?
//g.clipRect(mx, my, mw, mh);
if(solids != null) {
int lx, ly, dw, dh;
lx = from.x;
ly = from.y;
dw = lx - to.x;
dh = ly - to.y;
for(int i=0; i<nsolids; i++) {
g.setColor(solids[i]);
g.drawLine(lx, ly, lx+dw, ly+dh);
lx +=dw;
ly +=dh;
}
} else {
//g.setColor(bg);
g.setColor(Color.black);
int px = from.x-to.x, py = from.y-to.y;
g.drawLine(from.x, from.y, to.x, to.y);
}
g.setColor(oldfg);
//g.setClip(oldclip);
}
public Object hit(int x, int y) {
double k, d;
k = (double)(w*(y-from.y) - h*(x-from.x));
d = Math.sqrt(k*k / (w*w+h*h));
if(d<20.0) {
// near enough the line
return new ZZCursorVirtual(super.c);
}
return null;
}
}
public void makeAwtNote(FlobSet into, ZZCell view, ZZCell noteCell,
Rectangle rect, boolean NileOn ) {
Flob bgfl;
// noteCell kind of emulates viewcell... ugly or elegant, don't know
if(noteCell.s("d.cursor-cargo", -1)!=null) {
ZZCell naccursed = ZZCursorReal.get(noteCell);
awtNile.awtNileRaster(into, noteCell, naccursed, rect);
}
/*
if(NileOn) {
bgfl = new AwtBgFlob(rect.x, rect.y, 1, rect.width,
rect.height, noteCell) {
public Object hit(int x0, int y0) {
return null;
}
};
} else {
bgfl = new AwtBgFlob(rect.x, rect.y, 1, rect.width,
rect.height, noteCell);
}
*/
bgfl = new AwtBgFlob(rect.x-2, rect.y-2, 1, rect.width+4,
rect.height+4, noteCell);
((CellBgFlob)bgfl).setBg(Color.white);
CellFlobFactory2.addSolidColors(into, (CellBgFlob)bgfl);
into.add(bgfl);
}
public void raster(FlobSet into, FlobFactory fact,
ZZCell view, String[] dims, ZZCell accursed) {
ZZCell awtsyslist = AwtUtil.getAwtSysList(view);
AwtMetrics M = AwtUtil.getAwtMetrics(awtsyslist);
Dimension d = into.getSize();
if(!M.RealViewEquals(d)) {
M.setRealView(d, true);
M.cellRepr();
}
boolean nileOn = false;
ZZCell curb = view.h("d.bind", 1, true);
if(curb!=null) {
String mode = ZZCursorReal.get(curb).getText();
if(mode.indexOf("Nile") >= 0)
nileOn = true;
}
Dimension nDim;
Point nCoord = new Point();
Rectangle rect;
// if note is dragged, draw only that one
if(Awtool.dragNote != null) {
nCoord = M.mapToRealView(dragNote.getX(), dragNote.getY());
nDim = M.getRealDimension(dragNote.getX(), dragNote.getY(), dragNote.getDimension());
rect = new Rectangle(nCoord.x-(nDim.width>>1), nCoord.y-(nDim.height>>1),
nDim.width, nDim.height);
makeAwtNote(into, view, dragNote.getCell(), rect, nileOn);
return;
}
ZZCell activeCategory =
AwtUtil.getCursoredCell(Awtool.c_activeCategory, awtsyslist);
//view.getSpace().getCellByID("1051"); //getActiveCategory(view);
if(activeCategory==null) {
activeCategory =
awtsyslist.h(AwtUtil.d_categories,1).
s(AwtUtil.d_categories, -1).
getOrNewCell(AwtUtil.d_categories);
AwtUtil.setCursor(Awtool.c_activeCategory, activeCategory, awtsyslist);
}
Categories C = new Categories(activeCategory);
AwtNote[] validNotes = C.getValidNotes();
// 'renderedNotes': key = notecell, value = {int x, y, w, h}
Hashtable renderedNotes = new Hashtable();
Vector notFixedNotes = new Vector();
ZZCell noteCell, noteParams, categoryLinkCell;
AwtLink catlink;
AwtNote note;
int[] noteSize;
double y, x, yRowMax=0.0, w, h, gap=0.1;
for(int i=0; i<validNotes.length; i++) {
note = validNotes[i];
noteCell = note.getCell();
// only category notes have fixed position
if(note.getCategoryLink() == null) {
notFixedNotes.addElement(note);
continue;
}
nCoord = M.mapToRealView(note.getX(), note.getY());
nDim = M.getRealDimension(note.getX(),note.getY(),note.getDimension());
// importtant: notes' headcells as keys
renderedNotes.put(noteCell.h(AwtUtil.d_clone),
new int[] { nCoord.x, nCoord.y, nDim.width, nDim.height });
rect = new Rectangle(nCoord.x-(nDim.width>>1), nCoord.y-(nDim.height>>1),
nDim.width, nDim.height);
makeAwtNote(into, view, noteCell, rect, nileOn);
}
AwtUtil.quickSort(notFixedNotes, 0, notFixedNotes.size()-1,
new AwtUtil.ObjectComparator() {
public int compare(Object o1, Object o2) {
return (( ((AwtNote)o1).getHeight() <
((AwtNote)o2).getHeight() ) ? 1 : 0 );
}
});
y = 1.0-gap; x = gap;
for(Enumeration e=notFixedNotes.elements(); e.hasMoreElements();){
note = (AwtNote)e.nextElement();
noteCell = note.getCell();
w = note.getWidth();
if(x+w>1.0-gap) {
x = gap;
y += yRowMax;
yRowMax = 0;
}
h = note.getHeight();
note.setCoord(x+(w/2.0), y+(h/2.0));
x += (w+gap);
if(h>yRowMax) yRowMax = h;
nCoord = M.mapToRealView(note.getX(), note.getY());
nDim = M.getRealDimension(note.getX(), note.getY(), note.getDimension());
// importtant: notes' headcells as keys
renderedNotes.put(noteCell.h(AwtUtil.d_clone),
new int[] { nCoord.x, nCoord.y, nDim.width, nDim.height });
rect = new Rectangle(nCoord.x, nCoord.y, nDim.width,
nDim.height);
makeAwtNote(into, view, noteCell, rect, nileOn);
//fact.centerFlob(into, noteCell, noteCell, 1,
// nCoord, 0, 0, 1, nDim);
}
// render links
int[] toField, fromField;
ZZCell toc, fromc;
AwtLink al;
AwtLink[] validLinks = C.getAllValidLinks(true, true);
for(int i=0; i<validLinks.length; i++ ) {
al = validLinks[i];
toc = al.toHeadCell();
fromc = al.fromHeadCell();
//pa("LINKCELL:"+al.getCell());
//pa("TO:"+toc);
//pa("FROM:"+fromc);
if(toc == null || fromc == null) continue;
if(!renderedNotes.containsKey(toc) ||
!renderedNotes.containsKey(fromc)) continue;
toField = (int[])renderedNotes.get(toc);
fromField = (int[])renderedNotes.get(fromc);
//pa("CELL:"+al.getCell());
//pa("FROM(x):"+fromField[0]+" (y):"+fromField[1]);
//pa("FROM(x):"+toField[0]+" (y):"+toField[1]);
Flob alinkflob = new AwtLinkFlob(new Point(fromField[0], fromField[1]),
new Point(toField[0], toField[1]), al.getCell());
into.add(alinkflob);
}
if(M.GridOn) {
AwtUtil.renderGrid(into, M, -1.0, -1.0, 1.0, 1.0, Color.gray, 10);
}
return;
}
}

1016
Modules/awtool/Awtool.java Normal file

File diff suppressed because it is too large Load Diff

955
Modules/awtool/Awtool.zob Normal file
View File

@@ -0,0 +1,955 @@
/*
Awtool.zob
*
* Copyright (c) 2000-2001 Ted Nelson and Tuomas Lukka
* Copyright (c) 2000-2001 Kimmo Wideroos
*
* 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 Kimmo Wideroos (inspired by Benjamin Fallenstein's notemap module)
*/
/** Awt = A(ssociative) writing tool -demo
*/
package org.gzigzag.module;
import org.gzigzag.*;
import java.util.*;
import java.awt.*;
public abstract class Awtool implements FlobView, FlobSet.DragCursor, ZOb {
public static final String rcsid = "";
public static boolean dbg = true;
static void p(String s) { if(dbg) System.out.println(s); }
static void pa(String s) { System.out.println(s); }
STRUCTPARAMS {
/** View dimension (not in use now...) */
int viewWidth
= 600;
int viewHeight
= 600;
int viewX
= 100;
int viewY
= 100;
}
static boolean NileOn = false;
static AwtNote dragNote;
static Point dragOffs = new Point(0, 0);
static Point dragCoord = new Point(0, 0);
static boolean creatingNote = false;
static long focusChangedLastTime = -1; // millisecs
static AwtCursor c_cursor1 = new AwtCursor(Color.red, true);
static AwtCursor c_cursor2 = new AwtCursor(Color.gray, true);
static AwtCursor c_activeCategory = new AwtCursor(Color.orange, false);
static AwtCursor c_metrics = new AwtCursor(Color.white, false);
public boolean accept(Object o) {
if(!(o instanceof ZZCell)) return false;
return true;
}
static public Hashtable categ;
static public Hashtable notes;
static public Hashtable validNotes;
static class NotemapBM extends BooleanMesh {
public NotemapBM(ZZCell bStructure) { super(bStructure); }
public boolean testBelonging(ZZCell nhc, ZZCell category) {
for(ZZCell l=category.h(AwtUtil.d_clone).s(AwtUtil.d_to); l != null; l=l.s(AwtUtil.d_to) )
if(l.h(AwtUtil.d_from,1).h(AwtUtil.d_clone).equals(nhc)) return true;
return false;
}
}
/* categories are a kind of layers containing notes (i.e. (text) elements).
* this class provides with logical operations for categories (AND, OR).
* the resulting categories should be able to store permanently in zzspace.
* heavily under construction ...
*/
public class Categories extends ZObCellRepr {
private Hashtable AllNoteHeadCells = null;
private Hashtable AllNotes = null;
private Hashtable AllValidNotes = null;
private Hashtable ValidNotes = null;
private Hashtable K = new Hashtable();
private NotemapBM bm;
private String categoryName = "SCRATCH";
public boolean isCategory(ZZCell c) {
return (c.h(AwtUtil.d_clone).getRankLength(AwtUtil.d_categories)>1);
}
public Categories(ZZCell bStructure) {
setCell(bStructure);
_findCategories(bStructure);
bm = new NotemapBM(bStructure);
AllNotes = new Hashtable();
AllNoteHeadCells = new Hashtable();
AllValidNotes = new Hashtable();
ValidNotes = new Hashtable();
ZZCell note, chc, nhc;
for(Enumeration e = K.keys(); e.hasMoreElements(); ) {
// chc = category headcell
chc = ((ZZCell)e.nextElement());
for(ZZCell linkc = chc.s(AwtUtil.d_to); linkc != null;
linkc = linkc.s(AwtUtil.d_to) )
{
note = linkc.h(AwtUtil.d_from, 1);
nhc = note.h(AwtUtil.d_clone);
AllNotes.put(note, nhc);
if(!AllNoteHeadCells.containsKey(nhc))
// AllNoteHeadCells must keep track of all note headcells
AllNoteHeadCells.put(nhc, note);
if(AllValidNotes.containsKey(nhc))
// AllValidNotes store valid headcells AND clones
// all together
AllValidNotes.put(note, nhc);
else if(bm.evaluate(nhc)) AllValidNotes.put(note, nhc);
if(AllValidNotes.containsKey(note)) {
// If there exist 2 or more valid note clones, ValidNotes
// store note headcell (otherwise note clone).
if(ValidNotes.containsKey(nhc)) ValidNotes.put(nhc, nhc);
else ValidNotes.put(nhc, note);
}
}
}
}
private void _findCategories(ZZCell bStructure) {
if(isCategory(bStructure)) {
K.put(bStructure.h(AwtUtil.d_clone), bStructure);
return;
} else
{
_findCategories(bStructure.s("d.1"));
_findCategories(bStructure.s("d.2"));
}
}
public ZZCell[] getNoteCells() {
ZZCell[] n = new ZZCell[AllNotes.size()];
Enumeration e = AllNotes.elements();
int i = 0;
while (e.hasMoreElements()) {
n[i] = (ZZCell)e.nextElement(); i++;
}
return n;
}
public AwtNote[] getNotes() {
AwtNote[] n = new AwtNote[AllNotes.size()];
Enumeration e = AllNotes.elements();
ZZCell ncell;
int i = 0;
while (e.hasMoreElements()) {
ncell = (ZZCell)e.nextElement();
n[i] = (AwtNote)AwtUtil.readZObClone(ncell);
n[i].setCell(ncell);
i++;
}
return n;
}
public ZZCell[] getAllValidNoteCells() {
ZZCell[] ln = new ZZCell[AllValidNotes.size()];
int i = 0;
for(Enumeration e=AllValidNotes.keys(); e.hasMoreElements();) {
ln[i] = (ZZCell)e.nextElement();
i++;
}
return ln;
}
public AwtNote[] getAllValidNotes() {
AwtNote[] ln = new AwtNote[AllValidNotes.size()];
ZZCell ncell;
int i = 0;
for(Enumeration e=AllValidNotes.keys(); e.hasMoreElements();) {
ncell = (ZZCell)e.nextElement();
ln[i] = (AwtNote)AwtUtil.readZObClone(ncell);
ln[i].setCell(ncell);
i++;
}
return ln;
}
public ZZCell[] getValidNoteCells() {
ZZCell[] ln = new ZZCell[ValidNotes.size()];
int i = 0;
for(Enumeration e=ValidNotes.elements(); e.hasMoreElements(); ) {
ln[i] = (ZZCell)e.nextElement();
i++;
}
return ln;
}
public AwtNote[] getValidNotes() {
AwtNote[] ln = new AwtNote[ValidNotes.size()];
ZZCell ncell;
int i = 0;
for(Enumeration e=ValidNotes.elements(); e.hasMoreElements(); ) {
ncell = (ZZCell)e.nextElement();
ln[i] = (AwtNote)AwtUtil.readZObClone(ncell);
ln[i].setCell(ncell);
i++;
}
return ln;
}
public ZZCell[] getK() {
ZZCell[] cat = new ZZCell[K.size()];
Enumeration e = K.elements();
int i = 0;
while (e.hasMoreElements())
cat[i] = (ZZCell)e.nextElement(); i++;
return cat;
}
public ZZCell[] getAllValidLinkCells(boolean internal, boolean external) {
return _getvalidlinks(internal, external, AllValidNotes.keys());
}
public AwtLink[] getAllValidLinks(boolean internal, boolean external)
{
ZZCell[] linkcells = _getvalidlinks(internal, external, AllValidNotes.keys());
AwtLink[] links = new AwtLink[linkcells.length];
for(int i = 0; i<linkcells.length; i++ ) {
links[i] = (AwtLink)AwtUtil.readZObClone(linkcells[i]);
links[i].setCell(linkcells[i]);
}
return links;
}
public ZZCell[] getValidLinkCells(boolean internal, boolean external) {
return _getvalidlinks(internal, external, ValidNotes.elements());
}
public AwtLink[] getValidLinks(boolean internal, boolean external) {
ZZCell[] linkcells = _getvalidlinks(internal, external, AllValidNotes.keys());
AwtLink[] links = new AwtLink[linkcells.length];
for(int i = 0; i<linkcells.length; i++ ) {
links[i] = (AwtLink)AwtUtil.readZObClone(linkcells[i]);
links[i].setCell(linkcells[i]);
}
return links;
}
// Get the links in this category
private ZZCell[] _getvalidlinks(boolean internal, boolean
external, Enumeration noteEnum) {
Hashtable links = new Hashtable();
ZZCell nhc, note, trgnote;
for(Enumeration e=noteEnum; e.hasMoreElements();) {
note = (ZZCell)e.nextElement();
nhc = note.h(AwtUtil.d_clone);
if(external)
for(ZZCell el=nhc.s(AwtUtil.d_to); el != null; el=el.s(AwtUtil.d_to)) {
// note has global relations
trgnote = el.h(AwtUtil.d_from, 1);
if(AllNoteHeadCells.containsKey(trgnote)) links.put(el, el);
}
if(internal && !(external && note.equals(nhc)))
for(ZZCell il=note.s(AwtUtil.d_to); il != null; il=il.s(AwtUtil.d_to)) {
// note has categorywide relations
trgnote = il.h(AwtUtil.d_from, 1);
if(AllValidNotes.containsKey(trgnote)) links.put(il, il);
}
}
int s = links.size(), i=0;
ZZCell[] res = new ZZCell[s];
for(Enumeration e=links.elements(); e.hasMoreElements(); ) {
res[i] = (ZZCell)e.nextElement();
i++;
}
return res;
}
public String getZObName() {
return "Catecory/Layer";
}
/* store category back in cellstructure */
public String cellRepr(ZZCell start, boolean clone) {
ZZCell c, retCell, catCell = null;
AwtLink catlink = new AwtLink();
catCell.setText(getZObName());
catCell = catCell.getOrNewCell(AwtUtil.d_to);
AwtNote note;
AwtNote[] validNotes = getValidNotes();
for(int i=validNotes.length; i>=0; i--) {
note = validNotes[i];
catlink.setX(note.getX()); catlink.setY(note.getY());
catlink.cellRepr(catCell, false);
// note's centralcell is a clone of its (ZOb's) original
// central cell; that's why '...im2), true);'
note.cellRepr(catCell.getOrNewCell(AwtUtil.d_from), true);
catCell = catCell.getOrNewCell(AwtUtil.d_to);
}
return "";
}
}
/** return note cell, if possible
*/
static ZZCell getNoteCellOrCursor(Object ob) {
ZZCell c = null;
if(ob instanceof ZZCursor) c = ((ZZCursor)ob).get();
else if(ob instanceof ZZCell) c = (ZZCell)ob;
else return null;
ZZCell link = c.s(AwtUtil.d_from, -1);
if(link == null) return null;
if(link.s(AwtUtil.d_to, -1) == null) return null;
return c;
}
static public void nile_action(String id, ZZCell vc1, ZZCell vc2, String key,
ZZCursor cur) {
boolean split = false;
ZZCell viewCell = vc1;
ZZCell otherCell = vc2;
p("Nile action: id: '"+id+"' key: '"+key);
StringTokenizer st = new StringTokenizer(id);
String[] toks = new String[st.countTokens()];
for(int i=0; i<toks.length; i++)
toks[i] = st.nextToken();
int dir = 0;
Nile2Unit unit = null;
if(toks.length > 1) {
if(toks[1].equals("+")) dir = 1;
else if(toks[1].equals("-")) dir = -1;
if(toks.length > 2) {
if(toks[2].equals("CHAR"))
unit = new Nile2Unit.Char();
else if(toks[2].equals("WORD"))
unit = new Nile2Unit.Word();
else if(toks[2].equals("SENT"))
unit = new Nile2Unit.Sentence();
else if(toks[2].equals("PARA"))
unit = new Nile2Unit.Paragraph();
}
}
id = toks[0];
if(id.equals("Cursor")) {
p("Cursor: "+dir);
Nile2Ops.moveCursor(unit, viewCell, dir);
ZZUpdateManager.setFast(null);
}
else if(id.equals("AdjLeft")) {
Nile2Ops.adjust(unit, viewCell, -1, dir);
ZZUpdateManager.setFast(null);
}
else if(id.equals("AdjRight")) {
Nile2Ops.adjust(unit, viewCell, 1, dir);
ZZUpdateManager.setFast(null);
}
else if(id.equals("Hop")) {
Nile2Ops.hop(unit, viewCell, dir);
}
else if(id.equals("Mode")) {
Nile2Ops.setCursor(unit, viewCell, null);
if(split)
Nile2Ops.setCursor(unit, otherCell, null);
}
else if(id.equals("Insert")) {
Nile2Ops.insert(viewCell, key);
// Set the selection of other half to char mode, too
if(split)
Nile2Ops.setCursor(new Nile2Unit.Char(), otherCell, null);
}
else if(id.equals("BackSpace")) {
Nile2Ops.backspace(unit, viewCell);
}
else if(id.equals("Delete")) {
Nile2Ops.del(unit, viewCell);
}
else if(id.equals("BreakParagraph")) {
Nile2Ops.breakParagraph(unit, viewCell);
}
else if(id.equals("Tunnel")) {
if(otherCell != null) {
Nile2Ops.tunnel(unit, otherCell, viewCell, dir, false);
}
}
else if(id.equals("Transcopy")) {
if(otherCell != null) {
Nile2Ops.tunnel(unit, otherCell, viewCell, dir, true);
}
}
else if(id.equals("PUICopy")) {
ZZCell c = ZZCursorReal.get(viewCell);
String s = Nile2Ops.stringify(c);
ZZUtil.puiCopy(s);
}
/*
else if(id.equals("TraverseTranscopies")) {
Nile2Ops.traverseTranscopies(viewCell, dir);
}
*/
//Object ob = null;
//if(pt != null)
// ob = xi.getObjectAt(pt.x, pt.y);
if(id.equals("MouseSetCursor") && cur!=null) {
p("Setting cursor from mouse! Unit: "+unit);
if(cur.get().h("d.nile").equals(viewCell)) {
Nile2Ops.setCursor(unit, viewCell, cur);
} else
if(cur.get().h("d.nile").equals(otherCell)) {
Nile2Ops.setCursor(unit, otherCell, cur);
}
}
}
abstract public void raster(FlobSet into, FlobFactory fact,
ZZCell view, String[] dims, ZZCell accursed);
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) {
ZZUpdateManager.setFast(view);
Object ob = null;
AwtNote note = null;
AwtMetrics M;
ZZCell nc;
Point noteRVCoord = null;
double[] noteVVCoord = null;
double deltaX, deltaY;
if(pt != null && xi != null) ob = xi.getObjectAt(pt.x, pt.y);
nc = getNoteCellOrCursor(ob);
if(nc != null) {
note = (AwtNote)AwtUtil.readZObClone(nc);
note.setCell(nc);
}
boolean forceOrigoChange = false;
ZZCell AwtSystemList;
ZZCell vc = view.getViewcell();
pa("NOTECELL: "+nc);
pa("Note action! '"+id+"' key: "+key);
// is nile mode on?
boolean nileOn = false;
ZZCell curb = vc.h("d.bind", 1, true);
if(curb!=null) {
String mode = ZZCursorReal.get(curb).getText();
if(mode.indexOf("Nile") >= 0)
nileOn = true;
}
pa("OBJECT: "+ob);
boolean isC = false;
if(ob instanceof ZZCursor) isC = true;
pa("IS CURSOR?: "+isC);
// if we have object which is not cursor, then nile action is impossible
if(nileOn && !(!(ob instanceof ZZCursor) && (ob != null)) ) {
ZZCell nvc1 = AwtUtil.getCursoredCell(c_cursor1, vc);
ZZCell nvc2 = AwtUtil.getCursoredCell(c_cursor2, vc);
if(nvc1==null) return;
if(nvc1.s("d.cursor-cargo", -1)==null) {
ZZCursorReal.set(nvc1, nvc1);
ZZCursorReal.setOffs(nvc1, 0);
}
if(nvc2!=null)
if(nvc2.s("d.cursor-cargo", -1)==null) {
ZZCursorReal.set(nvc2, nvc2);
ZZCursorReal.setOffs(nvc2, 0);
}
nile_action(id, nvc1, nvc2, key, (ZZCursor)ob);
//Nile1.module.action(id,code,target,nview,cview,key,pt,xi);
return;
}
if(id.equals("TESTWIN")) {
AwtSystemList = target;
// set awt dims
AwtUtil.addDims(ZZDefaultSpace.findDefaultDimlist(code.getHomeCell()));
// Cursors
ZZCell curs = AwtSystemList.findText(AwtUtil.d_awtool, 1, "Cursors");
if(curs == null) {
ZZCell nCurs1, nCurs2, cat1;
ZZCell cursors = AwtSystemList.N(AwtUtil.d_awtool);
cursors.setText("Cursors");
cursors.N("d.1");
}
// View
ZZCell rastname, rl, rc = AwtSystemList.findText(AwtUtil.d_awtool, 1, "View");
if(rc == null) {
rc = AwtSystemList.N(AwtUtil.d_awtool);
rc.setText("View");
rl = rc.N("d.1");
rl.connect("d.2", 1, rl);
rl.setText("Awtool");
rastname = rl.N("d.1");
rastname.setText("Awtool.View1");
} else {
rl = rc.s("d.1");
rastname = rl.s("d.1");
}
// Bindings
ZZCell bindhome = AwtSystemList.findText(AwtUtil.d_awtool, 1, "Bind");
if(bindhome == null) {
bindhome = AwtSystemList.N(AwtUtil.d_awtool);
bindhome.setText("Bind");
bindhome = bindhome.N("d.1", 1);
//ZZDefaultSpace.mkCorner(bindhome, actions);
actions(bindhome.h("d.2", 1));
} else {
bindhome = bindhome.s("d.1");
}
// View metrics
ZZCell metr = AwtSystemList.findText(AwtUtil.d_awtool, 1, "Metrics");
if(metr == null) {
Dimension RV = new Dimension(400, 400);
Dimension VV = new Dimension(1000, 1000);
// create 'metrics collection'
metr = AwtSystemList.N(AwtUtil.d_awtool);
metr.setText("Metrics");
ZZCell mnew, metrList;
mnew = metrList = metr.N("d.1");
M = new AwtMetricsNormal(mnew, RV, VV, 0.0,0.0);
M.cellRepr();
mnew = mnew.N("d.2");
M = new AwtMetricsFC(mnew, RV, VV, 0.0, 0.0);
M.cellRepr();
mnew = mnew.N("d.2");
M = new AwtMetricsFC2(mnew, RV, VV, 0.0, 0.0);
M.cellRepr();
// make circle
mnew.connect("d.2", 1, metrList);
AwtUtil.setCursor(c_metrics, metrList, AwtSystemList);
} else {
ZZCell currentMetrics =
AwtUtil.getCursoredCell(c_metrics, AwtSystemList);
if(currentMetrics == null) {
currentMetrics = metr.s("d.1");
AwtUtil.setCursor(c_metrics, currentMetrics, AwtSystemList);
}
M = (AwtMetrics)AwtUtil.readZObClone(currentMetrics);
M.setCell(currentMetrics);
}
// searching for active category ...
ZZCell ac = AwtUtil.getCursoredCell(c_activeCategory, AwtSystemList);
if(ac == null) {
if(AwtSystemList.getRankLength(AwtUtil.d_categories)>1) {
ac = AwtSystemList.s(AwtUtil.d_categories);
} else {
ac = AwtSystemList.N(AwtUtil.d_categories);
ac.setText("* SCRATCH *");
}
AwtUtil.setCursor(c_activeCategory, ac, AwtSystemList);
}
ZZCell v = ZZDefaultSpace.newToplevelView(rc.getSpace(),
"awtool", 0, 0, M.RealView[0], M.RealView[1],
rl, null,
null, null,
null,
new Color(0xFFFFB1));
// Then, set bindings
ZZCell bcurs = v.getOrNewCell("d.bind", 1);
ZZCursorReal.set(bcurs, bindhome);
ZZCursorReal.setColor(bcurs, Color.black);
ZZCell awtc = v.h("d.2", 1).N("d.2");
awtc.setText("AwtSystemList");
ZZCursorReal.set(awtc, AwtSystemList);
// init shared cursors
ZZCell scursors = v.h("d.2",1).N("d.2");
scursors.setText("SharedCursors");
scursors.N("d.1");
return;
}
AwtSystemList = AwtUtil.getAwtSysList(view.getViewcell());
if(AwtSystemList == null && !id.equals("TESTWIN")) {
throw new ZZError("Awtool: AwtSystemList missing!!");
}
M = AwtUtil.getAwtMetrics(AwtSystemList);
if(id.equals("StartDrag")) {
if(note != null) {
dragNote = note;
noteRVCoord = M.mapToRealView(note.getX(), note.getY());
dragOffs.x = noteRVCoord.x - pt.x;
dragOffs.y = noteRVCoord.y - pt.y;
}
} else
if(id.equals("StopDrag") && dragNote != null) {
noteVVCoord = M.mapToVirtualView(pt.x + dragOffs.x, pt.y + dragOffs.y);
dragNote.setCoord(noteVVCoord[0], noteVVCoord[1]);
dragNote.cellRepr();
dragOffs.x = 0; dragOffs.y = 0;
dragNote = null;
} else
if(id.equals("Dragged") && dragNote != null) {
noteVVCoord = M.mapToVirtualView(pt.x + dragOffs.x, pt.y + dragOffs.y);
dragNote.setCoord(noteVVCoord[0], noteVVCoord[1]);
ZZUpdateManager.chg();
//dragNote.cellRepr();
} else
if(id.equals("StartResize")) {
if(note != null) {
dragNote = note;
noteRVCoord = M.mapToRealView(note.getX(), note.getY());
dragOffs.x = noteRVCoord.x - pt.x;
dragOffs.y = noteRVCoord.y - pt.y;
}
} else
if(id.equals("StopResize") && dragNote != null) {
noteVVCoord = M.mapToVirtualView(pt.x + dragOffs.x, pt.y + dragOffs.y);
dragNote.setCoord(noteVVCoord[0], noteVVCoord[1]);
dragNote.cellRepr();
dragOffs.x = 0; dragOffs.y = 0;
dragNote = null;
} else
if(id.equals("Resizing") && dragNote != null) {
} else
if(id.equals("StartCreatingNote")) {
dragCoord = pt;
// this is chanced to 'true' when dragging occurs
creatingNote = false;
} else
if(id.equals("CreatingNote")) {
creatingNote = true;
} else
if(id.equals("StopCreatingNote") && creatingNote) {
ZZCell newNoteCell;
AwtNote newNote;
int cx = (dragCoord.x+pt.x)>>1;
int cy = (dragCoord.y+pt.y)>>1;
double[] ndim, nvcenter = M.mapToVirtualView(cx, cy);
Dimension nd = new Dimension(Math.abs(dragCoord.x-pt.x), Math.abs(dragCoord.y-pt.y));
ndim = M.getVirtualDimension(cx, cy, nd);
ZZCell ac = AwtUtil.getCursoredCell(c_activeCategory, vc);
ZZCell noteCell =
ac.h(AwtUtil.d_to).N(AwtUtil.d_to).N(AwtUtil.d_from);
AwtUtil.createNewNote(noteCell, nvcenter, ndim);
// attach new note also to 'notes' dimension along
// active category cell.
ac.h(AwtUtil.d_notes, 1).connect(AwtUtil.d_notes, 1, noteCell);
dragCoord.x = 0;
dragCoord.y = 0;
creatingNote = false;
} else
if(id.equals("SetCursor1") && nc != null) {
ZZCell red = AwtUtil.getCursoredCell(c_cursor1, vc);
if(red.equals(nc)) return;
AwtUtil.setCursor(c_cursor2, red, vc);
AwtUtil.setCursor(c_cursor1, nc, vc);
if(red!=null) {
red.excise("d.nile-wins");
nc.connect("d.nile-wins", 1, red);
nc.connect("d.nile-wins", -1, red);
}
} else
if(id.equals("SetCursor2") && nc != null) {
ZZCell gray = AwtUtil.getCursoredCell(c_cursor2, vc);
if(gray.equals(nc)) return;
AwtUtil.setCursor(c_cursor1, gray, vc);
AwtUtil.setCursor(c_cursor2, nc, vc);
if(gray!=null) {
gray.excise("d.nile-wins");
nc.connect("d.nile-wins", 1, gray);
nc.connect("d.nile-wins", -1, gray);
}
} else
if(id.equals("NewLink")) {
ZZCell c1, c2;
c1 = AwtUtil.getCursoredCell(c_cursor1, vc);
c2 = AwtUtil.getCursoredCell(c_cursor2, vc);
if(c1 != null && c2 != null && c1 != c2) {
AwtUtil.createNewLink(c1, c2);
}
} else
if(id.equals("ChangeMetrics")) {
// save current metrics (focus, origo, etc.)
M.cellRepr();
ZZCell mc = AwtUtil.getCursoredCell(c_metrics, vc);
mc = mc.s("d.2");
AwtUtil.setCursor(c_metrics, mc, vc);
M = (AwtMetrics)AwtUtil.readZObClone(mc);
M.setCell(mc);
ZZUpdateManager.chg();
} else
if(id.equals("ResetOrigo")) {
//pa("ORIGO RESET!");
M.setOrigo(0.0, 0.0);
ZZUpdateManager.chg();
} else
if(id.equals("GridOnOff")) {
//pa("GRID ON/OFF!");
boolean gon = M.GridOn;
M.GridOn = gon ? false : true;
if(M.GridOn != gon) {
M.cellRepr();
}
ZZUpdateManager.chg();
} else
if(id.equals("FocusOrigoAndSelect")) {
long elapsedTime = Long.MAX_VALUE;
long cur = System.currentTimeMillis();
double[] vf1, vf2;
vf1 = M.mapToVirtualView(pt.x, pt.y);
M.setFocusOrigo(pt.x, pt.y, nc);
vf2 = M.mapToVirtualView(pt.x, pt.y);
M.moveOrigo(vf1[0]-vf2[0], vf1[1]-vf2[1]);
M.cellRepr();
if(focusChangedLastTime > 0) {
elapsedTime = cur - focusChangedLastTime;
focusChangedLastTime = -1;
} else {
focusChangedLastTime = cur;
}
pa("ELAPSED_TIME: "+elapsedTime);
if(elapsedTime < 1500) {
// 'doubleclick'-focus should change also origo
// this does not work reasonably
// forceOrigoChange = true;
forceOrigoChange = false;
} else { ZZUpdateManager.chg(); }
}
if(id.equals("ChangeOrigo") || forceOrigoChange) {
double[] vvp = M.mapToVirtualView(pt.x, pt.y);
// new origo is wanted to be in the center of realview
double[] realOrigo = M.mapToVirtualView(M.RealView[0]>>1,
M.RealView[1]>>1);
M.moveOrigo(vvp[0]-realOrigo[0], vvp[1]-realOrigo[1]);
M.cellRepr();
ZZUpdateManager.chg();
}
}
public ZOb newZOb(String id) {
if(id.equals("View1"))
return new AwtView1();
else
return null;
}
};
// This is really hacky part...
static ZZCell curAct;
static void a(String key, String act) { a(key, act, null); }
static void a(String key, String act, ZZCell next) {
curAct = curAct.N("d.2", 1);
curAct.setText(key);
ZZCell n = curAct.N("d.1", 1);
n.setText("Awtool." + act);
if(next != null)
next.insert("d.3", 1, n);
}
static void actions(ZZCell start) {
ZZCell awtact = start; awtact.setText("Awtool mode");
ZZCell nchar = awtact.N("d.1",1); nchar.setText("Nile char");
ZZCell nword = nchar.N("d.1", 1); nword.setText("Nile word");
ZZCell nsent = nword.N("d.1", 1); nsent.setText("Nile sent");
ZZCell npara = nsent.N("d.1", 1); npara.setText("Nile para");
ZZCell ncommon = npara.N("d.1", 1); ncommon.setText("Nile common");
curAct = nword;
// Annoying - these should be structurally
// describable!!!
a("MouseClicked1", "MouseSetCursor 0 WORD");
a("Backspace", "BackSpace 0 WORD");
a("Delete", "Delete 0 WORD");
a("Alt-Backspace", "Delete 0 WORD");
a("Ctrl-P", "Tunnel - WORD"); // P for pull
a("Ctrl-T", "Transcopy - WORD");
a("Left", "Cursor - WORD");
a("Right", "Cursor + WORD");
a("Shift-Left", "AdjLeft - WORD");
a("Shift-Right", "AdjRight + WORD");
a("Ctrl-Left", "AdjRight - WORD");
a("Ctrl-Right", "AdjLeft + WORD");
a("Alt-Left", "Hop - WORD");
a("Alt-Right", "Hop + WORD");
a("Enter", "BreakParagraph 0 WORD");
a("Up", "Cursor - SENT");
a("Down", "Cursor + SENT");
a("Alt-Up", "Hop - SENT");
a("Alt-Down", "Hop + SENT");
a("INSERT", "Insert", nchar);
a("Tab", "Mode 0 SENT", nsent);
// awtool specific
a("Alt-N", "NileOnOff", awtact);
curAct = nsent;
a("MouseClicked1", "MouseSetCursor 0 SENT");
a("Backspace", "BackSpace 0 SENT");
a("Delete", "Delete 0 SENT");
a("Alt-Backspace", "Delete 0 SENT");
a("Ctrl-P", "Tunnel - SENT"); // P for push
a("Ctrl-T", "Transcopy - SENT");
a("Left", "Cursor - SENT");
a("Right", "Cursor + SENT");
a("Shift-Left", "AdjLeft - SENT");
a("Shift-Right", "AdjRight + SENT");
a("Ctrl-Left", "AdjRight - SENT");
a("Ctrl-Right", "AdjLeft + SENT");
a("Alt-Left", "Hop - SENT");
a("Alt-Right", "Hop + SENT");
a("Enter", "BreakParagraph 0 SENT");
a("Up", "Cursor - PARA");
a("Down", "Cursor + PARA");
a("Alt-Up", "Hop - PARA");
a("Alt-Down", "Hop + PARA");
a("INSERT", "Insert", nchar);
a("Tab", "Mode 0 CHAR", nchar);
// awtool specific
a("Alt-N", "NileOnOff", awtact);
/*
curAct = npara;
a("MouseClicked1", "MouseSetCursor 0 PARA");
a("Backspace", "BackSpace 0 PARA");
a("Delete", "Delete 0 PARA");
a("Alt-Backspace", "Delete 0 PARA");
a("Left", "Cursor - PARA");
a("Right", "Cursor + PARA");
a("Shift-Left", "AdjLeft - PARA");
a("Shift-Right", "AdjRight + PARA");
a("Ctrl-Left", "AdjRight - PARA");
a("Ctrl-Right", "AdjLeft + PARA");
a("Alt-Left", "Hop - PARA");
a("Alt-Right", "Hop + PARA");
a("INSERT", "Insert");
a("Tab", "Mode 0 CHAR", nchar);
*/
curAct = nchar;
a("MouseClicked1", "MouseSetCursor 0 CHAR");
a("Left", "Cursor - CHAR");
a("Right", "Cursor + CHAR");
a("Backspace", "BackSpace 0 CHAR");
a("Delete", "Delete 0 CHAR");
a("Alt-Backspace", "Delete 0 CHAR");
a("INSERT", "Insert");
a("Tab", "Mode 0 WORD", nword);
a("Enter", "BreakParagraph 0 CHAR");
a("Ctrl-C", "PUICopy 0 CHAR");
a("Up", "Cursor - WORD");
a("Down", "Cursor + WORD");
// awtool specific
a("Alt-N", "NileOnOff", awtact);
// awtool acts
curAct = awtact;
a("MouseStartDrag", "StartDrag");
a("MouseDragged1", "Dragged");
a("MouseReleased1", "StopDrag");
a("Shift-MouseStartDrag", "StartCreatingNote");
a("Shift-MouseDragged1", "CreatingNote");
a("Shift-MouseReleased1", "StopCreatingNote");
a("Shift-MouseClicked3", "ChangeOrigo");
a("MouseClicked3", "FocusOrigoAndSelect");
a("Shift-MouseClicked1", "SetCursor2");
a("MouseClicked1", "SetCursor1");
a("l", "NewLink");
a("m", "ChangeMetrics");
a("g", "GridOnOff");
a("r", "ResetOrigo");
a("Alt-N", "NileOnOff", nchar);
}
}

View File

@@ -0,0 +1,78 @@
/*
BooleanMesh.java
*
* Copyright (c) 2000-2001 Ted Nelson and Tuomas Lukka
* Copyright (c) 2000-2001 Benjamin 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 Kimmo Wideroos
*/
package org.gzigzag.module;
import org.gzigzag.*;
import java.util.*;
public abstract class BooleanMesh {
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 String d_1 = "d.1"; static String d_2 = "d.2";
static public ZZCell bStructure = null;
static public Hashtable bOperators = new Hashtable();
/*
*/
public BooleanMesh(ZZCell bs) {
bStructure = bs;
bOperators.put("AND", new boolean[][]{{false, false}, {false, true}});
bOperators.put("OR", new boolean[][]{{false, true}, {true, true}});
bOperators.put("XOR", new boolean[][]{{false, true}, {true, false}});
}
public boolean evaluate(ZZCell nhc) { return evaluate(bStructure, nhc); }
private boolean evaluate(ZZCell bElem, ZZCell nhc) {
String bt = bElem.getText();
p("belem:"+bt+" c:"+nhc.getText());
ZZCell arg1, arg2;
int i = 0, j = 0;
if(bOperators.containsKey(bt)) {
// add exception handling here!
arg1 = bElem.s(d_1); arg2 = bElem.s(d_2);
p("arg1:"+arg1.getText());
p("arg2:"+arg2.getText());
if(evaluate(arg1, nhc)) i = 1;
if(evaluate(arg2, nhc)) j = 1;
p("i:"+i+" j:"+j);
boolean retv = ((boolean[][])bOperators.get(bt))[i][j];
p("RETV: "+retv);
return retv;
} else {
// compare bElem (=categoryname) and c
p("TEST! "+nhc.getText()+" =?= "+bElem.getText());
return testBelonging(nhc, bElem);
}
}
public abstract boolean testBelonging(ZZCell c, ZZCell category);
}

58
Modules/awtool/README Normal file
View File

@@ -0,0 +1,58 @@
A(ssociative) writing tool -demo
--------------------------------
Althought you cannot actually write with this demo at the moment,
it is (however) possible to
- create new notes by dragging mouse and keeping
mouse1-key pressed
- drag and drop notes created before
- link notes by attaching cursors (click mouse1 / shift-mouse1
on a note) to a pair of notes and pressing 'l' (uncapitalized 'L')
- change metrics by pressing 'm' (currently 3 possibilities)
- change focus (click mouse3-button)
- change origo (click shift-mouse3)
To start:
- create new action 'Awtool.TESTWIN' in zz-system
- use it to invoke awtool
About the view:
- Real view (rendered part) is mutable
- Virtual view is fixed, all objects' places
are based on virtual view coordinates (-1.0<x,y<1.0),
These in turn correspond with some pixel-coordinates.
- Origo (o) is related to Virtual view
- Focus (f) is related to Real view
------------------------------------
|(Virtual view 800x600, -1 ... 1) |
| ________________________ |
| |Real view | |
| |400x300 | |
| | | |
| | | |
| | | |
| | o=(0.0, 0.0)| |
| | | |
| | | |
| | f=(50, 250) | |
| | | |
| | | |
| ------------------------- |
| |
| |
| |
------------------------------------
Misc:
Special dimensions. Awtool uses its own system-dimension
'd.awtool', which stores the state of the applitude. So,
if you quit awtool and start it newly with datacursor pointing
to the same cell, you should end up with the old working-view
(layer or category of notes).

14
Modules/awtool/TODO Normal file
View File

@@ -0,0 +1,14 @@
TODO:
- Navigation between layers (=categories)
- Creation of new layers
- Logical operations (AND, OR, ..) between layers
-
- (more) ...
- ...
- rethink
- (more) ...
- ...

View File

@@ -0,0 +1,57 @@
/*
ZOb.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 Kimmo Wideroos
*/
package org.gzigzag.module;
import org.gzigzag.*;
import java.util.*;
import java.awt.*;
/** Absract class for ZObs which are able to be rolled back into the cellstructure.
*/
public abstract class ZObCellRepr {
private ZZCell _rootcell = null;
public ZZCell getCell() { return this._rootcell; }
public void setCell(ZZCell c) { this._rootcell = c; }
public String getZObClassName() {
String cn = getClass().getName();
int i = cn.lastIndexOf(".");
return cn.substring(i+1, cn.length());
}
abstract String getZObName();
/** Write the parameters of this ZOb back in the cellstructure.
* Returns a string describing the errors encountered, or null if
* everything went fine..
* @param start starting cell
* @param clone whether or not to make the new ZOb centralcell a clone
* of the former centralcell (if cells equal, the whole
* issue is trivial).
*/
abstract String cellRepr(ZZCell start, boolean clone);
public String cellRepr() {return cellRepr(getCell(), false); }
}

View File

@@ -0,0 +1,126 @@
/*
GraphBench.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.benchmark;
import org.gzigzag.*;
import java.util.*;
import java.awt.*;
/** Benchmark various graphics stuff.
*/
public class GraphBench {
public static final String rcsid = "$Id: GraphBench.java,v 1.2 2001/04/01 11:38:49 tjl Exp $";
static private void p(String s) { System.out.println(s); }
final Frame frame = new Frame();
{
frame.setSize(100,100);
frame.show();
}
final Font font = new Font("SansSerif", Font.PLAIN, 18);
final FontMetrics fontmetrics = frame.getFontMetrics(font);
ZZBench b = new ZZBench();
/** To be overridden by subclasses.
* Some graphics implementations, notably Java2D, require
* setting flags or hints in the Graphics object to improve
* rendering. We abstract the flags in this routine
* which all the rendering tests call.
*/
public void setFlags(Graphics g) {
}
static final int X(int i) {
return 50 + (i % 3) * 10;
}
static final int Y(int i) {
return 50 + (i % 5) * 10;
}
static final Color c(int i) {
i %= 2;
if(i==0) return Color.blue;
else if(i==1) return Color.red;
else return Color.green;
}
Canvas c = new Canvas();
{
c.setSize(300,800);
frame.add(c);
frame.pack();
}
Image getImage(int w, int h) {
return c.createImage(w,h);
}
public void runRender(final Graphics g) {
g.setFont(font);
setFlags(g);
b.run(new Object[] {
"DRAWTEXT6", "",
new Runnable() {
int i = 0;
public void run() {
g.setColor(c(i));
g.drawString("abcdef", X(i), Y(i));
i++;
}
},
"DRAWTEXT20", "",
new Runnable() {
int i = 0;
public void run() {
g.setColor(c(i));
g.drawString("abcdefghijklmnopqrst", X(i), Y(i));
i++;
}
},
});
}
public void run() {
p("Into image 300x300");
runRender(getImage(300,300).getGraphics());
p("Direct");
runRender(c.getGraphics());
b.run(new Object[] {
"FNTMETR6", "FontMetrics",
new Runnable() {
public void run() {
int i = fontmetrics.stringWidth("abcdef"); } },
"FNTMETR20", "FontMetrics 20 chars",
new Runnable() {
public void run() {
int i = fontmetrics.stringWidth("abcdefghijklmnopqrst"); } },
});
}
public static void main(String[] argv) {
new GraphBench().run();
System.exit(0);
}
}

16
Modules/benchmark/README Normal file
View File

@@ -0,0 +1,16 @@
GZigZag Benchmarking module
This module contains various pieces of code that test relative speeds
of various operations. The point is
1) provide a good basic intuition of what is fast and slow in Java,
for purpose of choosing implementation methods
2) provide a test for different JVM's efficiency on different tasks
(there are surprising diffrences here)
3) provide a testbed for zigzag algorithms and possible extensions,
such as the constraint model where the feasibility from a speed
perspective can be studied without building the whole system.

View File

@@ -0,0 +1,100 @@
/*
ZZBench.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.benchmark;
import org.gzigzag.*;
import java.util.*;
/** Test speeds of various simple java operations,
* provide a generic simple speed-test framework.
*/
public class ZZBench {
public static final String rcsid = "$Id: ZZBench.java,v 1.3 2001/04/01 11:38:49 tjl Exp $";
static private void p(String s) { System.out.println(s); }
public void runTest(String s, Runnable r) {
// Start it up so that the JIT is ready
for(int i=0; i<32; i++) r.run();
// run more and more until we get over 3 secs of time.
int nt = 20;
long diff = 0;
do {
long t0 = System.currentTimeMillis();
for(int i = nt; i >= 0; i--)
r.run();
long t1 = System.currentTimeMillis();
nt *= 2;
diff = t1 - t0;
} while(diff < 1500);
p(s+": "+nt+" iter, "+diff+" ms, per iter: "+
(long)(1000000 * diff / (float)nt) + " ns");
}
/** Run the given tests, time them and print out the results.
* Each test should be relatively fast to execute.
* @param tests Triplets of String, String, Runnable:
* first string is a unique ID for the test,
* second string a human-readable explanation (without newlines)
* and the Runnable is the test itself.
*/
public void run(Object[] tests) {
for(int i=0; i<tests.length; i+= 3) {
p("Running "+tests[i]+": "+tests[i+1]);
Runnable r = (Runnable)tests[i+2];
runTest((String)tests[i], r);
}
}
public static void main(String[] argv) {
ZZBench b = new ZZBench();
b.run(new Object[] {
"PUTHASH", "Put a string into a hash (same place)",
new Runnable() { Hashtable h = new Hashtable();
public void run() { h.put("foo", "foo"); } },
"PUTGETCASTHASH",
"Put, get and cast a string into a hash (same place)",
new Runnable() { Hashtable h = new Hashtable(); String s;
public void run() { h.put("foo", "foo");
s = (String)h.get("foo"); } },
"CREATE", "Create an object",
new Runnable() { Object o;
public void run() { o = new Object(); } },
"CREATE4I", "Create an object with four ints inside",
new Runnable() { Object o;
public void run() { o = new Object() {
int i1, i2, i3, i4;
}; } },
"EMPTY", "empty function",
new Runnable() { public void run() { } },
"INCRINT", "Increment a member integer",
new Runnable() { int i; public void run() { i++; } },
"ASSIGN", "assign a member to another",
new Runnable() { ZZBench o = new ZZBench(); ZZBench b;
public void run() { b = (ZZBench)o; } },
"CLSCAST", "Class-cast a member, store to another",
new Runnable() { Object o = new ZZBench(); ZZBench b;
public void run() { b = (ZZBench)o; } },
});
}
}

View File

@@ -0,0 +1,95 @@
/*
Java2DBench.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.benchmark;
import org.gzigzag.*;
import java.util.*;
import java.awt.*;
/** Benchmark Java2D: antialiasing, rotation etc.
*/
public class Java2DBench extends GraphBench {
public static final String rcsid = "$Id: Java2DBench.java,v 1.2 2001/04/01 11:38:49 tjl Exp $";
static private void p(String s) { System.out.println(s); }
RenderingHints speedHints = new RenderingHints(null);
RenderingHints qualityHints = new RenderingHints(null);
{
speedHints.put(RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_SPEED);
qualityHints.put(
RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
qualityHints.put(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
qualityHints.put(RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_QUALITY);
qualityHints.put(RenderingHints.KEY_STROKE_CONTROL,
RenderingHints.VALUE_STROKE_PURE);
}
int cur;
public void setFlags(Graphics g0) {
Graphics2D g = (Graphics2D)g0;
if(cur < 2) {
p("ROTATED");
g.rotate(0.5);
} else {
p("STRAIGHT");
}
switch(cur % 2) {
// case 0:
// p("NO HINTS");
// break;
case 0:
p("SPEED");
g.setRenderingHints(speedHints);
break;
case 1:
p("QUALITY");
g.setRenderingHints(qualityHints);
break;
}
}
int maxcase = 4;
public void run() {
p("Into image 300x300");
for(cur = 0; cur <= maxcase; cur++)
runRender(getImage(300,300).getGraphics());
p("Direct");
for(cur = 0; cur <= maxcase; cur++)
runRender(c.getGraphics());
}
public static void main(String[] argv) {
new Java2DBench().run();
System.exit(0);
}
}

227
Modules/database/DB0.java Normal file
View File

@@ -0,0 +1,227 @@
/*
DB0.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.module;
import org.gzigzag.*;
import java.sql.*;
import java.io.*;
import java.text.*;
import java.util.*;
import java.awt.*;
public class DB0 {
public static final String rcsid = "$Id: DB0.java,v 1.9 2000/10/18 14:35:32 tjl Exp $";
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); }
static public class StrComp implements ZZUtil.Comparator {
public int compare(ZZCell c1, ZZCell c2) {
return c1.getText().compareTo(c2.getText());
}
}
static public class DHeadComp implements ZZUtil.Comparator {
DHeadComp(String dim) { this.dim = dim; }
String dim;
public int compare(ZZCell c1, ZZCell c2) {
return c1.h(dim, -1).getText().compareTo(
c2.h(dim, -1).getText());
}
}
static public void insertCells(ZZCell head, String x, String y,
ResultSet rs,
String maincol,
Hashtable id2col
) throws SQLException {
ResultSetMetaData meta = rs.getMetaData();
int n = meta.getColumnCount();
ZZCell[] hdr = new ZZCell[n];
ZZCell[] cur = new ZZCell[n];
ZZCell nextnew = head;
int mcid = -1;
int idid = -1;
for(int i=0; i<n; i++) {
nextnew = cur[i] = hdr[i] = nextnew.N(x, 1);
String name = meta.getColumnName(i+1);
hdr[i].setText(name);
if(maincol != null && name.equals(maincol))
mcid = i;
if(name.equals("id"))
idid = i;
}
if(maincol != null && mcid < 0) throw new Error("Invalid main col id");
ZZCell curhead = head;
while(rs.next()) {
String id = null;
ZZCell mcol = null;
ZZCell prev = null;
for(int i=0; i<n; i++) {
String s = rs.getString(i+1);
if(s==null) s="(null)";
cur[i] = cur[i].N(y, 1);
cur[i].setText(s);
if(prev != null)
prev.connect(x, 1, cur[i]);
prev = cur[i];
if(i == mcid) {
mcol = cur[i];
/* curhead.connect("d.2", cur[i]);
curhead = cur[i]; */
}
if(i == idid)
id = s;
}
if(id != null && mcol != null)
id2col.put(id, mcol);
}
for(int i=0; i<n; i++) {
ZZUtil.sortRank(hdr[i], y, 1, new StrComp(), false);
}
// ZZUtil.sortRank(head,"d.2", 1, new StrComp(), false);
rs.close();
}
static public ZZModule module = new ZZModule() {
public void action(String id, ZZCell code,
ZZCell target,
ZZView v, ZZView cv,
String key, Point pt,
ZZScene xi) {
try {
if(id.equals("READMEMS")) {
synchronized(target.getSpace()) {
ZZSpace zz = target.getSpace();
String x = "d.1";
String y = "d.2";
Hashtable id2mem = new Hashtable();
Hashtable id2sig = new Hashtable();
String url = "jdbc:postgresql://himalia.mit.jyu.fi/zz";
String usr = "tjl";
String pwd = "";
Class.forName("org.postgresql.Driver");
Connection db = DriverManager.getConnection(url, usr, pwd);
Statement st = db.createStatement();
ZZCell n = target.N("d.3", 1);
n.setText("members");
ResultSet rs = st.executeQuery("select * from members");
insertCells(n, x, y, rs, "name", id2mem);
n = n.N("d.3", 1); n.setText("sigs");
rs = st.executeQuery("select * from sigs");
insertCells(n, x, y, rs, "name", id2sig);
n = n.N("d.3", 1); n.setText("positions");
rs = st.executeQuery("select * from positions");
insertCells(n, x, y, rs, null, null);
// ZZCell title = target.N();
// title.setText("<Linux>");
// Create people rank in alphabetical order
rs = st.executeQuery("select * from members order by name");
ZZCell prev = null;
while(rs.next()) {
ZZCell curr = (ZZCell)id2mem.get(rs.getString(1));
if(prev != null) prev.connect("d.people", 1, curr);
prev = curr;
}
// Create sig rank in alphabetical order
rs = st.executeQuery("select * from sigs order by name");
prev = null;
while(rs.next()) {
ZZCell curr = (ZZCell)id2sig.get(rs.getString(1));
if(prev != null) prev.connect("d.insigs", 1, curr);
prev = curr;
}
p("Rels: ");
// Insert relcells after the positions table
rs = st.executeQuery("select * from positions");
while(rs.next()) {
String pers = rs.getString(1);
String sig = rs.getString(2);
// p("Rel: "+pers+" "+sig);
ZZCell pc = (ZZCell)id2mem.get(pers);
ZZCell sc = (ZZCell)id2sig.get(sig);
if(pc == null || sc == null)
throw new Error("No such relation "+pers+" "+sig);
ZZCell relc = pc.N("d.insigs",1);
sc.insert("d.people", 1, relc);
relc.setText("+");
}
rs.close();
// Sort the ranks of the in-which-sigs tables.
for(Enumeration e = id2mem.elements();
e.hasMoreElements(); ) {
ZZCell c = (ZZCell)e.nextElement();
ZZUtil.sortRank(c, "d.insigs", 1,
new DHeadComp("d.people"), false);
}
for(Enumeration e = id2sig.elements();
e.hasMoreElements(); ) {
ZZCell c = (ZZCell)e.nextElement();
ZZUtil.sortRank(c, "d.people", 1,
new DHeadComp("d.insigs"), false);
}
st.close();
db.close();
}
} /* else if(id.equals("IMPORT")) {
// XXX How to give 2 arguments: the file name and the home cell
(new XML()).load(new File(target.getText()),
}*/
} catch(SQLException e) {
System.out.println(e);
e.printStackTrace();
} catch(ClassNotFoundException e) {
System.out.println(e);
e.printStackTrace();
}
}
};
}

View File

@@ -0,0 +1,68 @@
#!/usr/bin/perl
#
# Create a sample database.
# Use the linux kernel CREDITS file as input.
print <<'STOP';
DROP TABLE members;
DROP TABLE positions;
DROP TABLE sigs;
CREATE TABLE members (
id INT4,
name TEXT,
address TEXT,
phone TEXT,
email TEXT,
PRIMARY KEY(id)
);
CREATE TABLE positions (
person INT4,
sig INT4
/* type TEXT */
);
CREATE TABLE sigs (
id INT4,
name TEXT,
PRIMARY KEY(id)
);
STOP
$/ = "\n\n";
$id = 0;
while(<>) {
/^\s*N:/ or next;
s/'//g;
my %h;
for(split "\n") {
/^([A-Z]): (.*)$/ or next;
push @{$h{$1}}, $2;
}
$phone = int(1000000 + rand 9000000);
$phone =~ s/(...)(....)/\1-\2/g;
print "INSERT INTO members VALUES ($id, '$h{N}[0]', '$h{S}[0]', '$phone', '$h{E}[0]');\n";
$id++;
last if $id > 100;
}
$sid = 0;
for(qw/filesys mm drivers boot console vfs/) {
print "INSERT INTO sigs VALUES ($sid, '$_');\n";
$sid++;
}
my %pos;
for(1..120) {
$pers = int rand $id;
$sig = int rand $sid;
next if $pos{$pers}{$sig}++;
print "INSERT INTO positions VALUES ($pers, $sig);\n";
}

View File

@@ -0,0 +1,18 @@
-- Taulut
SELECT * FROM members;
SELECT * FROM positions;
SELECT * FROM sigs;
-- Kaikkien tekijöiden kaikki projektit
SELECT members.name,sigs.name FROM members, positions, sigs WHERE members.id = positions.person AND sigs.id = positions.sig ORDER BY members.name, sigs.name;
-- Kaikkien projektien kaikki tekijät
SELECT sigs.name,members.name FROM members, positions, sigs WHERE members.id = positions.person AND sigs.id = positions.sig ORDER BY sigs.name, members.name;

29
Modules/database/zz.sql Normal file
View File

@@ -0,0 +1,29 @@
CREATE TABLE members (
id INT4,
fname TEXT,
lname TEXT,
address TEXT,
phone TEXT,
email TEXT,
PRIMARY KEY(id)
);
CREATE TABLE positions (
person INT4,
sig INT4
/* type TEXT */
);
CREATE TABLE sigs (
id INT4,
name TEXT,
PRIMARY KEY(id)
);
INSERT INTO members VALUES
(1,'Henna','Koskinen','Kuusikkokuja 4','321-564356','henna43@hotmail.com');
INSERT INTO sigs VALUES
(1,'helicopters');
INSERT INTO positions VALUES
(1,1);

View File

@@ -0,0 +1,162 @@
/*
Calendar2.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.module;
import org.gzigzag.*;
import java.awt.*;
import java.util.*;
import java.io.*;
public class Calendar2 implements FlobView, ZOb {
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); }
static public ZZModule module = new ZZModule() {
public ZOb newZOb(String id) {
if(id.equals("R"))
return new Calendar2();
return null;
}
};
STRUCTPARAMS {
Font nfont
= new Font("SansSerif", Font.PLAIN, 16);
Font bfont
= new Font("SansSerif", Font.BOLD, 16);
}
FontMetrics nfm, bfm;
INITIALIZE {
nfm = FONTMETRICS(nfont);
bfm = FONTMETRICS(bfont);
}
final String[] txts = new String[] {
"Vk", "M", "T", "K", "T", "P", "L", "S"
};
public void raster(FlobSet into, FlobFactory fact,
ZZCell view, String[] dims, ZZCell accursed) {
Dimension s = into.getSize();
final int x = s.width/2 / 10;
final int y = s.height / 10;
final int w = s.width/2 - 2 * x;
final int h = s.height - 2 * y;
final int x2 = x + s.width/2;
final int xm = w / 8;
final int ym = h / 7;
Dimension c = fact.getSize(null, 1);
int cw = c.width;
int ch = c.height;
// Find the first day of the month
ZZCell curday = accursed.h("d.event").h("d.events");
ZZCell mfirst = curday.h("d.day");
if(mfirst.s("d.weekday") == null) {
into.add(new Renderable() {
{ d = 1; }
public void render(Graphics g) {
g.setColor(Color.red);
g.setFont(new Font("SansSerif", Font.BOLD, 32));
g.drawString("Not calendar data", 20, 40);
}
});
return;
}
int day = Integer.parseInt(mfirst.s("d.weekday").t());
final int week = Integer.parseInt(mfirst.s("d.weekday",2).t());
into.add(new Renderable() {
{ d = 50; }
public void render(Graphics g) {
Color old = g.getColor();
g.setColor(Color.gray);
g.setFont(nfont);
g.drawRect(x, y, w, h);
g.drawLine(x+xm, y, x+xm, y+h);
g.drawLine(x, y+ym, x+w, y+ym);
int fh = nfm.getHeight();
for(int i=0; i<8; i++) {
int tw = nfm.stringWidth(txts[i]);
g.drawString(txts[i], x+(xm-tw)/2+i*xm, y+(ym+fh)/2);
}
for(int i=0; i<6; i++) {
int tw = nfm.stringWidth(""+(i+week));
g.drawString(""+(i+week), x+(xm-tw)/2, y+(ym+fh)/2+(i+1)*ym);
}
g.setColor(new Color(0xb0b0b0));
for(int i=0; i<5; i++) {
g.drawLine(x, y+(2+i)*ym, x+w, y+(2+i)*ym);
}
}
});
LoopDetector l = new LoopDetector();
int row = 0;
for(ZZCell mday = mfirst; mday != null; mday = mday.s("d.day")) {
l.detect(mday);
boolean hasEv = (mday.s("d.events") != null);
fact.makeFlob(into, mday, mday, (hasEv ? (float)1.8 : 1),
x+1+(1+day)*xm, y+1+(1+row)*ym, 2, xm-2, ym-2);
if(mday == curday) {
// Ring it
}
day += 1;
if(day >= 7) row ++;
day %= 7;
}
row = 0;
int fh = nfm.getHeight();
for(ZZCell curev = curday.s("d.events");
curev != null && curev != curday;
curev = curev.s("d.events")) {
fact.makeFlob(into, curev, curev, 1,
x2 + 10, y + (ch+2)*row, 1, w-10-cw, ch);
ZZCell txt = curev.s("d.event");
fact.makeFlob(into, txt, txt, 1,
x2 + w - cw, y + (ch+2)*row, 1, cw, ch);
row ++;
}
}
}
// vim: set syntax=java :

View File

@@ -0,0 +1,116 @@
/*
ClockCellView.zob
*
* 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.module;
import org.gzigzag.*;
import java.util.*;
import java.awt.*;
/** A cell view that shows the daytime demo clock, using a scene flob.
* For use with ideosyncratic cell view. Create the cell to be shown as a
* clock. Posward on d.3, connect the clock cell to a d.2 rank of appointments
* in the regular DayTimeDemo structure (see DayTimeDemo.zob and the
* CyberText article pictures). Then, from the clock cell negwards on
* d.cellview create a new cell and write the cell view's name, e.g.
* "Clock Cellview," in it. From that cell, create a new cell poswards on d.1
* and write "DayTimeDemo.C" (of course w/o quotes) in it. Use F2 to switch
* to the ideosyncratic cell view, and the clock cell should change its
* appereance to a DayTimeDemo clock. (Best viewed with StretchVanishing or
* Quad view, so that it's not shown that small.)
*/
public class ClockCellView implements FlobFactory, ZOb {
public static final String rcsid = "$Id: ClockCellView.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 {
Font txtfont
= new Font("Serif", Font.BOLD, 14);
Font clkfont
= new Font("SansSerif", Font.PLAIN, 11);
}
public Dimension getSize(ZZCell c, float fract) {
return new Dimension((int)(150*fract), (int)(150*fract));
}
DayTimeDemo dtd = new DayTimeDemo();
INITIALIZE {
dtd.txtfont = txtfont;
dtd.clkfont = clkfont;
dtd.txtfm = FONTMETRICS(txtfont);
dtd.clkfm = FONTMETRICS(clkfont);
}
public Flob makeFlob(FlobSet into, ZZCell c, ZZCell handleCell,
float fract,
int x, int y, int d, int w, int h) {
FlobSet sc = new FlobSet(new Dimension(w, h), Color.white, Color.black,
ScalableFont.fmComp);
dtd.raster(sc, null, null, null, c.getRootclone().h("d.3", 1));
SceneFlob sf = new SimpleSceneFlob(x, y, d, w, h, c, sc);
CellFlobFactory1.addSolidColors(into, sf, sf);
into.add(sf);
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 :

View File

@@ -0,0 +1,174 @@
/*
DayTimeDemo.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.module;
import org.gzigzag.*;
import java.awt.*;
import java.util.*;
import java.io.*;
/** A simple raster showing times of day along a circle.
* The structure is described along three dimensions:
* hierarchy, sibling and cross-reference (d.1, d.2 and d.3 by default).
* On these, the hierarchy is arranged as a corner list with an empty
* corner cell, and the cross-references are simply siblings
* connected.
* <p>
* The structure is specified as a rank on d.2 of d.1 lists:
* start, end, type, text. Type's root clone will have the color
* of the type on d.1.
* <p>
* The whole rank on d.2 is read.
*/
public class DayTimeDemo implements FlobView, ZOb {
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); }
static public ZZModule module = new ZZModule() {
public ZOb newZOb(String id) {
if(id.equals("R"))
return new DayTimeDemo();
if(id.equals("C"))
return new ClockCellView();
return null;
}
};
STRUCTPARAMS {
Font txtfont
= new Font("Serif", Font.BOLD, 14);
Font clkfont
= new Font("SansSerif", Font.PLAIN, 11);
}
FontMetrics txtfm, clkfm;
INITIALIZE {
txtfm = FONTMETRICS(txtfont);
clkfm = FONTMETRICS(clkfont);
}
static final String next = "d.2";
static final String hier = "d.1";
static final String cross = "d.3";
static final int time2deg(String time) {
int i = time.indexOf(":");
if(i < 0) return 0;
String t1 = time.substring(0,i);
String t2 = time.substring(i+1);
int h = -1;
int m = -1;
try {
h = Integer.parseInt(t1);
m = Integer.parseInt(t2);
} catch(NumberFormatException e) {
System.out.println("Exc: "+e);
}
return -(int)(360 * (h*60.0 + m) / (24*60)) - 90;
}
static final Point deg2pt(int deg, int w, int h) {
return new Point((int)(w/2*Math.cos(deg * Math.PI / 180)),
-(int)(h/2*Math.sin(deg * Math.PI / 180)));
}
public void raster(FlobSet into, FlobFactory fact,
ZZCell view, String[] dims, ZZCell accursed) {
Dimension s = into.getSize();
final int x = s.width / 10;
final int y = s.height / 10;
final int w = s.width - 2 * x;
final int h = s.height - 2 * y;
// Clock face.
into.add(new Renderable() {
{ d = 50; }
public void render(Graphics g) {
Color old = g.getColor();
g.setColor(Color.black);
g.setFont(clkfont);
for(int i=0; i<24; i++) {
int and = time2deg(i+":00");
// g.fillArc(x, y, w, h, and, 1);
Point p = deg2pt(and, w, h);
p.x *= 1.05;
p.y *= 1.05;
p.translate(x+w/2, y+h/2);
g.drawLine(x+w/2, y+h/2, p.x, p.y);
if(i % 2 == 0) {
String str = i+":00";
g.drawString(str, p.x - clkfm.stringWidth(str)/2 , p.y);
}
}
g.setColor(old);
}
});
for(
ZZCell cur = accursed.h("d.1", -1).h("d.2", -1);
cur != null;
cur = cur.s("d.2", 1)) {
ZZCell c = cur;
String start = c.getText(); c = c.s("d.1", 1);
String end = c.getText(); c = c.s("d.1", 1);
ZZCell meet = c.h("d.clone", -1).s("d.1", 1);
String col = "0xffffff";
if(meet != null) col = meet.getText();
c = c.s("d.1", 1);
final String text = c.getText();
final int sang = time2deg(start);
final int eang = time2deg(end);
final Color color = Color.decode(col);
// now, render it.
into.add(new Renderable() {
{ d = 50; }
public void render(Graphics g) {
g.setColor(color);
g.fillArc(x, y, w, h, sang, eang-sang);
}});
into.add(new Renderable() {
{ d = 45; }
public void render(Graphics g) {
g.setFont(txtfont);
Point p = deg2pt((sang+eang)/2, w, h);
p.x *= 0.8;
p.y *= 0.8;
p.translate(x+w/2, y+h/2);
g.setColor(Color.black);
g.drawString(text, p.x, p.y);
g.fillOval(p.x-8, p.y-8, 8, 8);
}});
}
}
}
// vim: set syntax=java :

83
Modules/extern/Extern.java vendored Normal file
View File

@@ -0,0 +1,83 @@
/*
Extern.java
*
* Copyright (c) 2000, Ted Nelson, Tuomas Lukka and Vesa Parkkinen
*
* 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 Vesa Parkkinen
*/
package org.gzigzag.module;
import org.gzigzag.*;
import java.util.*;
import java.io.*;
import java.awt.*;
/**
* Module to handle external commands. At the moment only
* EXECBROWSER is implemented. To start netscape execbrowser with
* empty target cell. If there is text in the target cell,
* netscape -remote openURL("") is executed.
*/
public class Extern {
public static final String rcsid = "$Id: Extern.java,v 1.4 2000/09/19 10:32:02 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); }
static public ZZModule module = new ZZModule() {
public void action(String id, ZZCell code,
ZZCell target,
ZZView v, ZZView cv,
String key, Point pt,
ZZScene xi) {
try {
p("Extern ACTION!");
/*
* XXX:
* Add a chech to see whether a netscape or mozilla
* is running.
*
*/
if(id.equals("EXECBROWSER")) {
Process p = null;
String s = target.getText();
if ( ! s.equals( "" ) ){
p("netscape -remote openURL(" + s + ")" );
p = Runtime.getRuntime().exec(
"netscape -remote openURL(" + s + ") ");
p("" + p);
}
else {
Runtime.getRuntime().exec("netscape");
}
} else {
pa("NO SUCH METHOD!! ");
}
}
catch (IOException ex){
p("" + ex);
}
}
};
}

View File

@@ -0,0 +1,283 @@
/*
HyperGenealogy.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.module;
import org.gzigzag.*;
import java.awt.*;
import java.util.*;
import java.io.*;
/** A simple keyframe-based lifeline/meeting tracer.
* There is: one cell for each meeting, one cell for each person
* and one cell for each person of a meeting.
* We plot the cells of the people and meetings.
* The meeting cell can have a short label. The fuller explanation
* should be elsewhere.
* <p>
* Dimension names give the dimension along which to find the cell
* with the number, except "time", which shows the keyframes.
* <p>
* All numbers are floats between 0 and 1.
* <p>
* There must be a root cell which starts the list of all persons
* on d.persons and the timeline on d.events.
*/
public class HyperGenealogy implements FlobView, ZOb {
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); }
static public ZZModule module = new ZZModule() {
public ZOb newZOb(String id) {
if(id.equals("R"))
return new HyperGenealogy();
return null;
}
public void action(String id,
ZZCell code,
ZZCell target,
ZZView view, ZZView cview, String key, Point pt, ZZScene xi) {
}
};
STRUCTPARAMS {
Font meetfont
= new Font("Serif", Font.BOLD, 11);
}
FontMetrics meetfm;
INITIALIZE {
meetfm = FONTMETRICS(meetfont);
}
static public class dc {
/** The dimension from the meeting cell to the participants,
* and from the root to the peoples' cells.
*/
final String persons = "d.persons";
/** The dimension from the person's cell to the events in his life,
* and from the root cell to all timeline cells.
* All these cells should go forwards in the "time" dimension.
*/
final String events = "d.events";
/** The dimension from a timeline cell to meeting cell.
*/
final String at = "d.at";
}
static dc d = new dc();
public float tofloat(ZZCell c) throws NumberFormatException {
return (Float.valueOf(c.getText())).floatValue();
}
/** Return the value the given cell has for the particular dimension.
* This routine understands the special dimension <code>time</code>,
* which it takes to mean the number at the headcell of
* <code>d.persons</code>
* and <code>d.at</code>. That cell is assumed to be on the timeline.
*/
public float dim(ZZCell c, String dimname) {
try {
ZZCell dc;
if(dimname.equals("time")) {
dc = c.h(d.persons, -1).h(d.at, -1);
if(dc == c) dc = null;
} else {
dc = c.s(dimname, 1);
}
if(dc == null) return -1;
return tofloat(dc);
} catch(NumberFormatException e) {
return -1;
}
}
/**
* @param from Meeting cell
*/
public void place(FlobSet into, int x, int y, int w, int h,
FlobFactory fact,
String[] dims, ZZCell from, int depthleft) {
from = from.h(d.persons);
for(ZZCell c = from.s(d.persons, 1);
c != null;
c = c.s(d.persons, 1)) {
if(into.findFlob("", c) != null)
return;
float dx = dim(c, dims[0]);
if(dx < 0) return;
float dy = dim(c, dims[1]);
if(dy < 0) return;
Flob flob = fact.placeFlob(into, from, c,
1,
(int)(x + dx * w), (int)(y + dy * h),
1,
(float)0.5, (float)0.5);
Flob f2 = fact.placeFlob(into, c.h(d.events), c,
1,
(int)(x + dx * w), (int)(y + dy * h + flob.h/2),
1,
(float)0.5, (float)0.0);
f2.flobPath = "evPers";
if(depthleft <= 0) continue;
ZZCell n = c.s(d.events, 1);
if(n != null)
place(into, x, y, w, h, fact, dims, n, depthleft-1);
n = c.s(d.events, -1);
if(n != null)
place(into, x, y, w, h, fact, dims, n, depthleft-1);
}
}
/** Place the cells at a given instant of time.
*/
public void placeTime(FlobSet into, int x, int y, int w, int h,
FlobFactory fact,
String[] dims, ZZCell from, float at) {
// This assumes the root...
ZZCell root = from;
LoopDetector ld = new LoopDetector();
p("Placetime");
for(ZZCell p = root.s(d.persons); p != null; p = p.s(d.persons)) {
ld.detect(p);
// Find the right time interval. Move poswards until greater
// or eq than current.
ZZCell prevev = null;
float prevt = 0;
float t = 0;
ZZCell ev;
p("Pt1: "+p);
for(ev = p.s(d.events); ev != null; ev = ev.s(d.events)) {
t = dim(ev, "time");
p("Pt2: "+ev+" "+t);
if(t >= at) break;
prevev = ev;
prevt = t;
}
p("Pt3: "+prevev+" "+ev+" ");
float dx, dy;
if(ev == null) continue;
if(prevev == null) {
if(t > at) continue;
dx = dim(ev, dims[0]); if(dx < 0) continue;
dy = dim(ev, dims[1]); if(dy < 0) continue;
} else {
float f = 1 - (at - prevt) / (t - prevt);
// Now we've got it in the aim... get the coordinates
// and interpolate.
float dx0 = dim(prevev, dims[0]); if(dx0 < 0) continue;
float dx1 = dim(ev, dims[0]); if(dx1 < 0) continue;
float dy0 = dim(prevev, dims[1]); if(dy0 < 0) continue;
float dy1 = dim(ev, dims[1]); if(dy1 < 0) continue;
dx = f * dx0 + (1-f) * dx1;
dy = f * dy0 + (1-f) * dy1;
}
Flob flob = fact.placeFlob(into, p, p,
1,
(int)(x + dx * w), (int)(y + dy * h),
1,
(float)0.5, (float)0.5
);
// ZZCell
}
}
// If accursed cell is a timeline cell, do all persons
public void raster(final FlobSet into, FlobFactory fact,
ZZCell view, String[] dims, ZZCell accursed) {
Dimension s = into.getSize();
int x = s.width / 10;
int y = s.height / 10;
int w = s.width - 2 * x;
int h = s.height - 2 * y;
if(accursed.s(d.at, 1) != null) {
placeTime(into, x, y, w, h, fact, dims,
accursed.h(d.events), tofloat(accursed));
} else {
place(into, x, y, w, h, fact, dims, accursed.h(d.persons), 3);
}
// selection: 3 next/prev meetings of current person,
// 1 next/prev of those he met.
final LineDecor.Builder ldb = new LineDecor.Builder(into, null);
final LineDecor.Builder ldbm = new LineDecor.Builder(into, Color.red);
final Hashtable done = new Hashtable();
into.iterDepth(new FlobSet.DepthIter() {
final void dline(Flob from, String dim, int dir,
LineDecor.Builder bu) {
ZZCell c = from.c.s(dim, dir);
if(c == null) return;
if(done.get(c) != null) return;
Flob to = into.findFlob("", c);
if(to == null) return;
//draw the line
bu.l(from.x, from.y+from.h/2, to.x, to.y+to.h/2);
}
public void act(Flob[] flobs, int start, int n) {
ldb.startl(4*n, flobs[start].d);
ldbm.startl(4*n, flobs[start].d);
for(int i=start; i<start+n; i++) {
Flob cur = flobs[i];
if(cur.flobPath != "") continue;
done.put(cur.c, cur.c);
// see if we have positive or negative connections
// on d.events and draw lines if we do.
dline(cur, d.events, -1, ldb);
dline(cur, d.events, 1, ldb);
// see if we have positive or negative connections
// on d.persons and draw lines
dline(cur, d.persons, -1, ldbm);
dline(cur, d.persons, 1, ldbm);
}
ldb.endl();
ldbm.endl();
}
}, true);
ZZUtil.showFlobDims(into, fact, view, 2);
}
}
// vim: set syntax=java :

View File

@@ -0,0 +1,117 @@
/*
DimRecursor.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;
import java.awt.*;
import java.util.*;
/** The dimension recursion the Vanishing view did formerly.
* XXX remove verbose debugging messages
*/
public class DimRecursor extends Iter.Any {
public static final String rcsid = "$Id: DimRecursor.java,v 1.1 2000/11/16 20:28:53 bfallenstein Exp $";
public static final boolean dbg = false;
static final void p(String s) { if(dbg) System.out.println(s); }
public DimRecursor(String[] dims, Iter.Dim iter, boolean included,
int maxlevel) {
this.dims = dims;
this.iter = iter;
this.included = included;
this.maxlevel = maxlevel;
this.higher = new Vector[dims.length];
this.curr = new Vector[dims.length];
}
public Iter.Dim iter;
public String[] dims;
public int dim, level;
protected Enumeration enum;
protected Vector[] curr, higher;
protected int higherdim, maxlevel;
protected static final Object NULL = new Object();
public void doStart() {
Vector v = new Vector();
v.addElement(root);
enum = v.elements();
higher[0] = v;
for(int i=0; i<dims.length; i++) {
curr[i] = new Vector();
}
dim = 0; level = 0; higherdim = 0;
}
public Iter.Step getNext() {
if(level == 0) {
iter.start(root, dims[0]);
level = 1;
} else {
iter.next();
p("Got next: "+iter.here);
}
while(iter.here == null) {
p("null");
while(!enum.hasMoreElements()) {
if(level > 1) {
higherdim++;
p("no el on hdim "+higherdim);
if(higherdim == dim) higherdim++;
}
if(level == 1 || higherdim >= dims.length) {
p("Iter.Dims -- no higher dim on dim "+dim);
dim++;
higherdim = 0;
if(dim >= dims.length) {
p("Iter.Dims -- no dim on level "+level);
level++;
if(level > maxlevel) return null;
dim = 0; higherdim = 1;
p("Iter.Dims level: "+level);
boolean doContinue = false;
for(int d=0; d<dims.length; d++) {
if(curr[d].size() > 0) doContinue = true;
higher[d] = curr[d];
curr[d] = new Vector();
}
if(!doContinue) return null;
}
}
if(level > 1) enum = higher[higherdim].elements();
else enum = higher[0].elements();
}
iter.start((Iter.Step)enum.nextElement(), dims[dim]);
}
curr[dim].addElement(iter.here);
p("ret: "+iter.here.cell);
return iter.here;
}
public void stop() { iter.stop(); }
}

View File

@@ -0,0 +1,177 @@
/*
EnumVanishingView.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, based on VanishingView 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 EnumVanishingView implements FlobView, ZOb {
public static final String rcsid = "$Id: EnumVanishingView.zob,v 1.1 2000/11/16 20:28:53 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); }
// 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
= 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;
}
// XXX This should be a structparam later on.
FlobDecorator linker = new StdLinks();
public void raster(FlobSet into, FlobFactory fact,
ZZCell view, String[] dims, ZZCell accursed) {
Dimension fs = into.getSize();
// Precalculate sizes and gaps.
int[] gaps = new int[depth];
Dimension[] size = new Dimension[depth+1];
float[] sizfact = new float[depth+1];
float xf = initmul[0], xf0 = xf;
float yf = initmul[1], yf0 = yf;
sizfact[0] = yf;
Dimension d0 = fact.getSize(null, yf);
Dimension d = (varsize ? fact.getSize(accursed, yf) : d0);
for(int i=0; i<depth; i++) {
xf *= shrink[0];
yf *= shrink[1];
if(!varsize) {
Dimension dc = new Dimension();
size[i+1] = dc;
dc.width = (int)(d.width * xf/xf0);
dc.height = (int)(d.height * yf/yf0);
}
sizfact[i+1] = yf;
gaps[i] = (int)(gap * xf);
}
d.width *= centermul[0];
d.height *= centermul[1];
// flob depth multiplier and offset.
// flob depth = d1 + dm*level
int d1 = 1;
int dm = 10;
int maxd = d1 + dm * depth;
Iter.Alter alter = new Iter.Alter();
alter.included = false;
DimRecursor dim = new DimRecursor(dims, alter, true, depth);
Iter.Limited limit = new Iter.Limited();
limit.iter = dim;
limit.n = depth;
Iter.Once once = new Iter.Once();
once.iter = limit;
once.start(new Iter.Step(accursed));
Point ctr = new Point(fs.width/2, fs.height/2);
Flob flob0 = fact.centerFlob(into, accursed, accursed, sizfact[0],
ctr, 0, 0, d1, d);
once.here.info = flob0;
p("Start recursing really");
for(ZZCell c = once.next(); c != null; c = once.next()) {
Flob f = (Flob)once.here.from.info;
p("Flob: "+f+" from: "+once.here.from);
if(f == null) throw new ZZError("XXX no flob found");
int dir = alter.ind>0 ? 1 : -1;
int dpt = once.here.nth;
// Alignments
int fxa, fya, txa, tya;
if(dim.dim == 0) { fxa=dir; txa=-dir; fya=0; tya=0; }
else if(dim.dim == 1) { fxa=0; txa=0; fya=dir; tya=-dir; }
else { fxa=dir; fya=dir; txa=-dir; tya=-dir; }
Point p = f.getPoint(fxa, fya);
Point q = ZZUtil.movePoint(p, fxa, fya, gaps[dpt]);
Flob g = fact.centerFlob(into, c, c, sizfact[dpt], q, txa, tya,
d1+dpt*dm, size[dpt]);
once.here.info = g;
p("To "+once.here+" assign "+g);
}
linker.decorate(into, "", view);
// Do the dimensions.
if(true)
ZZUtil.showFlobDims(into, fact, view, 3);
}
}

212
Modules/iter/Iter.java Normal file
View File

@@ -0,0 +1,212 @@
/*
Iter.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;
import java.util.*;
/** Help for iterating along ranks in various ways.
* A proposed alternative to ZZIter.
* XXX make constructors work (how?)
* XXX remove verbose debugging messages
* XXX make MUCH faster!
*/
public class Iter {
public static final String rcsid = "$Id: Iter.java,v 1.1 2000/11/16 20:28:53 bfallenstein Exp $";
public static final boolean dbg = false;
static final void p(String s) { if(dbg) System.out.println(s); }
static public class Step {
public ZZCell cell;
public Step from;
public int nth;
public Object info;
// Do not need to be set (then, dir == null).
public String dim = null;
public int dir;
public Step(ZZCell c) { from = null; cell = c; nth = 0; }
public Step(Step f, ZZCell c, int n) { from = f; cell = c; nth = n; }
public Step go(ZZCell c) { return new Step(this, c, nth+1); }
public Step go(String dim, int dir) {
p("step "+cell+" "+dim+" "+dir);
ZZCell tocell = cell.s(dim, dir);
p("tocell "+tocell);
if(tocell == null) return null;
Step res = go(tocell);
p("res.cell "+res.cell);
res.dim = dim; res.dir = dir;
return res;
}
public String toString() { return "[Iter.Step for "+cell+"]"; }
}
static public abstract class Any {
public Step here, root;
public boolean included;
protected abstract Step getNext();
protected void doStart() {}
// public Any(boolean included) { this.included = included; }
public ZZCell start(Step s) {
here = s; root = s;
doStart();
if(!included) next();
return here != null ? here.cell: null;
}
public ZZCell next() {
if(here == null) return null;
here = getNext();
return here != null ? here.cell : null;
}
public boolean more() { return here != null; }
public void stop() { here = null; }
}
static public abstract class Dim extends Any {
String dim; int fdir = 1;
// public Dim(String dim, int fdir, boolean included) {
// this.dim = dim;
// this.fdir = fdir;
// this.included = included;
// }
public void start(Step s, String dim) {
this.dim = dim; start(s);
}
public void start(Step s, String dim, int fdir) {
this.dim = dim; this.fdir = fdir; start(s);
}
}
static public class Rank extends Dim {
protected Step getNext() { return here.go(dim, fdir); }
}
static public class Alter extends Dim {
/** Current position negwards and poswards. */
Step neg, pos;
public int ind;
public void doStart() {
neg = here.go(dim, -fdir);
pos = here.go(dim, fdir);
p("alter start: "+pos+" "+neg+" // "+(pos==root?"yes":"no"));
ind = 0;
}
protected Step getNext() {
if(neg == null && pos == null) { p("alter null"); return null; }
// Trick: always change ind, only after see if we have something
// to return. If not, recurse and get the next one from the other side.
Step res;
if(ind <= 0) {
ind = -ind;
ind ++;
if(pos == null)
return getNext();
res = pos;
pos = pos.go(dim, fdir);
p("alter pos from "+res+" to "+pos);
} else {
ind = -ind;
if(neg == null)
return getNext();
res = neg;
neg = neg.go(dim, -fdir);
p("alter neg from "+res+" to "+neg);
}
p("alter: "+res);
// Don't loop XXX doesn't work yet
// if(neg!=null && pos!=null && neg.cell==pos.cell) return null;
return res;
}
public void stop() {
if(ind > 0) neg = null;
else if(ind < 0) pos = null;
else super.stop();
}
}
static public abstract class Filter extends Any {
protected Any iter;
protected abstract boolean check();
protected void accepted() {}
// public Filter(Any iter) { this.iter = iter; }
public ZZCell start(Step s) {
iter.start(s);
here = iter.here;
doStart();
return here.cell;
}
public ZZCell next() {
if(here == null) return null;
do {
p("Filter get next...");
iter.next();
here = iter.here;
p("Filter check: "+here);
if(here == null) return null;
} while(!check());
accepted();
p("Filter accept "+here);
return here.cell;
}
public void stop() { iter.stop(); }
protected Step getNext() { throw new ZZError("getNext on Filter"); }
}
static public class Once extends Filter {
protected Hashtable done;
protected void doStart() { done = new Hashtable(); }
protected boolean check() { return done.get(here.cell) == null; }
protected void accepted() { done.put(here.cell, here.cell); }
}
static public class Limited extends Filter {
protected int n, donenum;
// public Limited(Any iter, int n) { this.iter = iter; this.n = n; }
protected void doStart() { donenum = 0; }
protected boolean check() {
if(donenum > n*n*2) return false;
return iter.here.nth < n;
}
protected void accepted() { donenum++; }
}
}

1
Modules/iter/README Normal file
View File

@@ -0,0 +1 @@
Some experiments for advanced ways of iteration through the structure.

View File

@@ -0,0 +1,91 @@
/*
ZZMbox.java
*
* Copyright (c) 2000, 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.io.*;
/** A simple class to use the Linux joystick API.
* A separate thread is used to read in the blocking mode from the
* joystick and the appropriate callbacks are made.
*/
public class LinuxJoystick implements Runnable {
public static final String rcsid = "$Id: LinuxJoystick.java,v 1.3 2000/09/19 10:32:03 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); }
FileInputStream in;
Thread t = new Thread(this);
public LinuxJoystick(File f) {
try {
in = new FileInputStream(f);
t.start();
} catch(Exception e) {
throw new Error("Couldn't open joystick");
}
}
public synchronized void run() {
try {
byte[] bpacket = new byte[8];
int[] packet = new int[8];
while(true) {
int n = in.read(bpacket);
p("Read "+n);
for(int i=0; i<8; i++) {
packet[i] = bpacket[i];
if(packet[i] < 0) packet[i] += 256;
}
p("R: "+
packet[0]+" "+
packet[1]+" "+
packet[2]+" "+
packet[3]+" "+
packet[4]+" "+
packet[5]+" "+
packet[6]+" "+
packet[7]);
long ms = packet[0] + (packet[1]<<8) + (packet[2]<<16)
+ (packet[3]<<24);
int value = packet[4]+((packet[5]&0x7F)<<8);
if((packet[5]&0x80)!=0)
value -= 32768;
int type = packet[6];
int num = packet[7];
p("EV: "+ms+" "+value+" "+type+" "+num);
}
} catch(Exception e) {
throw new Error("Couldn't open joystick");
}
}
/** For testing. */
static public void main(String argv[]) {
LinuxJoystick j = new LinuxJoystick(new File("/dev/js0"));
}
}

133
Modules/mbox/SingleMail.zob Normal file
View File

@@ -0,0 +1,133 @@
/*
SingleMail.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.module.mbox;
import org.gzigzag.*;
import java.awt.*;
/** A presentation of a single e-mail message.
*/
public class SingleMail implements FlobView, ZOb {
public static final boolean dbg = true;
static final void p(String s) { if (dbg) System.out.println(s); }
STRUCTPARAMS {
Font hfont = new Font("SansSerif", Font.PLAIN, 14);
Font dfont = new Font("SansSerif", Font.BOLD, 14);
Font bfont = new Font("Monospaced", Font.PLAIN, 12);
int tabstop = 8;
}
int headerh;
int bodyh;
FontMetrics hfm;
Color headerc, datac, bodyc;
String tabs[];
INITIALIZE {
headerh = (hfont.getSize() > dfont.getSize()? hfont.getSize()
: dfont.getSize());
bodyh = bfont.getSize();
hfm = FONTMETRICS(hfont);
headerc = datac = bodyc = Color.red;
tabs = new String[tabstop + 1];
tabs[0] = "";
for (int i = 1; i < tabstop + 1; i++)
tabs[i] = tabs[i - 1] + '\t';
}
public void raster(FlobSet into, FlobFactory fact,
ZZCell view, String[]dims, ZZCell accursed) {
Dimension d = into.getSize();
ZZCell handle = accursed.h("d.ref", -1);
ZZCell c = handle;
ZZCell f;
int y = 0;
c = c.s("d.handle", 1);
while (c != null && y <= d.height) {
f = c.s("d.1", 1);
if (f != null) // Header record
y = addHeader(into, y, c, f);
else
y = addBody(into, y, c);
c = c.s("d.handle", 1);
}
}
int addHeader(FlobSet into, int y, ZZCell c, ZZCell d) {
p(into.toString() + y + c.toString() + d.toString());
p("C: " + c.getID());
p("D: " + d.getID());
String field = c.getText();
String data = d.getText();
y += headerh;
into.add(new TextDecor(0, y, field, headerc, hfont));
into.add(new TextDecor(hfm.stringWidth(field) + 10, y,
data, datac, dfont));
return y;
}
int addBody(FlobSet into, int y, ZZCell c) {
String body = c.getText();
int start = 0;
int end = -1;
while (end < body.length()) { // Split into lines
end = body.indexOf('\n', end + 1);
if (end == -1)
end = body.length();
y += bodyh;
if (start < end) {
String line = body.substring(start, end);
StringBuffer buf = new StringBuffer();
int offs = 0;
int pos = 0;
int tab = -1;
while (tab < line.length()) { // Expand tabs
tab = line.indexOf('\t', tab + 1);
if (tab == -1)
tab = line.length();
buf.append(line.substring(pos, tab));
if (tab < line.length()) {
int tablen = tabstop - ((tab + offs) % tabstop);
p("Tab: " + tablen);
buf.append(tabs[tablen]);
offs = offs + tablen - 1;
}
pos = tab + 1;
}
into.add(new TextDecor(0, y, new String(buf), bodyc, bfont));
}
start = end + 1;
}
return y;
}
}
// vim: set syntax=java :

View File

@@ -0,0 +1,398 @@
/**
* ZZDateParser.java
* Created: Wed Feb 9 08:20:13 2000
*
*
* Copyright (c) 1999, Ted Nelson, Tuomas Lukka and Vesa Parkkinen
*
* 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.
*
*
* @author Vesa Parkkinen
* @version 0.2 ( might even work, sometimes )
*
*/
package org.gzigzag.module;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.StringTokenizer;
import java.util.TimeZone;
import java.util.SimpleTimeZone;
/**
* This class tries to parse RFC 822 formatted dates.
* I haven't yet seen the spec, but this seems to work with
* few strings taken from my mails.
* OK, now that i've seen the spec, this should pretty much be capable
* of parsing the dates.
* Except the zone name information is not used.
* <p>
*/
public class ZZDateParser {
public static final String rcsid = "$Id: ZZDateParser.java,v 1.9 2000/09/19 10:32:03 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); }
/**
* Month names used in date string.
*/
static String[] months = { "Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec" };
static String[] days = { "Mon",
"Tue",
"Wed",
"Thu",
"Fri",
"Sat",
"Sun" };
/**
* Method for parsing RFC 822 formatted dates to calendar objects.
* @param String d Date string in RFC 822 format.
* @return Calendar calendar having the date and time from RFC 822
* ERROR CHECKING IS MISSING !
* Will be added someday soon.
*/
public static Calendar parse(String d){
int year = 1;
int month = 1;
int date = 1;
String day;
int time[];
int gmt_diff[];
d.trim();
try{
/* check whether we have day name */
StringTokenizer t = new StringTokenizer( d, " " );
//if ( t.countTokens() > 1 ){
//day = t.nextToken();
// t.nextToken( " " );
//}
//String tok;
try {
day = t.nextToken( );
date = (int) Integer.parseInt( day );
} catch( NumberFormatException nfe ) {
//day = t.nextToken();
//t.nextToken( );
date = (int) Integer.parseInt( t.nextToken( ) );
}
//try{
String smonth = t.nextToken();
for ( int i = 0; i < 12 ; i++ )
if( smonth.equals( months[ i ] ) ){
month = i ;
break;
}
year = (int) Integer.parseInt( t.nextToken() );
time = parseTime( t.nextToken() );
String[] id;
String s;
int off = 0;
if( t.hasMoreTokens() )
gmt_diff = parseTz(t.nextToken());
//if( ! t.hasMoreTokens() ){
if( t.hasMoreTokens() ){
gmt_diff = parseTz(t.nextToken());
off = gmt_diff[0] * 60 * 60 * 1000 + gmt_diff[1] * 60 * 1000;
id = TimeZone.getAvailableIDs( off );
if ( id.length > 0 )
s = id[0];
else s = "";
} else {
s = "GMT";//t.nextToken();
}
Calendar
calendar = new GregorianCalendar(
new SimpleTimeZone( off, s ) );
calendar.set( year, month, date,
time[0], time[1], time[2] );
return calendar;}
catch (Exception e){
pa("Not a rfc822 date! Fix it :" + e);
return new GregorianCalendar();
}
}
/**
* What we've got here is a method to parse
* Calendar to RFC 822 formatted date String.
*
* @param Calendar calendar having the date and time from RFC 822
* @return String d Date string in RFC 822 format.
*
*/
public static String parse(Calendar c){
String dateString = "";
/* parse day string */
int d = c.get(Calendar.DAY_OF_WEEK);
String day = "";
switch ( d ){
case (Calendar.MONDAY):
day = days[0];
break;
case (Calendar.TUESDAY):
day = days[1];
break;
case (Calendar.WEDNESDAY):
day = days[2];
break;
case (Calendar.THURSDAY):
day = days[3];;
break;
case (Calendar.FRIDAY):
day = days[4];;
break;
case (Calendar.SATURDAY):
day = days[5];;
break;
case (Calendar.SUNDAY):
day = days[6];;
break;
default:
day = "";
break;
}
//*/
//day = days[d];
if ( day.length() == 3 )
dateString += day +", ";
int dm = c.get(Calendar.DAY_OF_MONTH);
if( dm < 1 || dm > 31 ) dm = 1;
dateString += "" + dm + " " ;
int m = c.get(Calendar.MONTH);
String month = "";
/*
switch ( m ){
case (Calendar.JANUARY):
month = months[0];
break;
case (Calendar.FEBRUARY):
month = months[1];
break;
case (Calendar.MARCH):
month = months[2];
break;
case (Calendar.APRIL):
month = months[3];
break;
case (Calendar.MAY):
month = months[4];
break;
case (Calendar.JUNE):
month = months[5];
break;
case (Calendar.JULY):
month = months[6];
break;
case (Calendar.AUGUST):
month = months[7];
break;
case (Calendar.SEPTEMBER):
month = months[8];
break;
case (Calendar.OCTOBER):
month = months[9];
break;
case (Calendar.NOVEMBER):
month = months[10];
break;
case (Calendar.DECEMBER):
month = months[11];
break;
default:
month = months[0];
}
*/
month = months[m];
dateString += month + " ";
int hour = c.get(Calendar.HOUR_OF_DAY);
String hh = ""+ hour;
hh = addZeros(hh,2);
int min = c.get(Calendar.MINUTE);
String mm = ""+ min;
mm = addZeros(mm,2);
int sec = c.get(Calendar.SECOND);
String ss = ""+ sec;
ss = addZeros(ss,2);
dateString += hh +":" + mm + ":" + ss + " " ;
// tz
int tz = c.get(Calendar.ZONE_OFFSET);
int tz_h = tz / ( 60 * 60 * 1000 );
int tz_m = ( tz % ( 60 * 60 * 1000 ) ) / 60 * 1000;
String t = addZeros("" + Math.abs(tz_h), 2);
t += addZeros("" + tz_m, 2);
if( tz_h < 0 )
dateString += "-";
if( tz_h == 0 && tz_m == 0 )
dateString += "GMT";
else dateString += ""+ t;
return dateString;
}
private static String addZeros(String s,int count){
int l = s.length();
if ( l < count )
for ( int i = l; i < count;i++){
s = "0" + s;}
return s;
}
private static int[] parseTime( String time ){
int[] comp = { 0, 0, 0 };
StringTokenizer tt = new StringTokenizer(time,":");
if( tt.hasMoreTokens() )
comp[0] = (int)Integer.parseInt(tt.nextToken());
else return comp;
if( tt.hasMoreTokens() )
comp[1] = (int)Integer.parseInt(tt.nextToken());
else return comp;
if( tt.hasMoreTokens() )
comp[2] = (int)Integer.parseInt(tt.nextToken());
return comp;
}
/* XXX TODO: add parsing of zone names if needed. */
private static int[] parseTz( String tz ){
int[] comp = { 0, 0 };
int negative = 1;
tz.trim();
if( tz.startsWith( "-" ) ){
negative = -1;
}
int l = tz.length();
String s;
StringTokenizer tt = new StringTokenizer( tz.substring( 1, l ) );
if ( tt.hasMoreTokens() )
s = tt.nextToken();
else s = tz.substring( 1, l );
int aa;
try {
aa = (int) Integer.parseInt( s );
}
catch( Exception e ) {
return comp;
}
comp[0] = negative * (int) aa / 100;
// do we need this
comp[1] =/* negative * */ (int) aa % 100;
return comp;
}
/*
public static void main(String[] argv){
//Calendar c = ZZDateParser.parse("Tue, 15 Feb 2000 23:57:42 GMT");
Calendar c = ZZDateParser.parse("Mon, 14 Feb 2000 18:04 -0200");
//Calendar c = ZZDateParser.parse("Sun, 13 Feb 2000 18:04:26 -0200");
//System.out.println(c.toString());
//System.out.println(c.getTime().getTime());
//System.out.println(c.get(Calendar.DATE));
//System.out.println(c.get(Calendar.MONTH));
//System.out.println("ZONE_OFFSET: "
// + (c.get(Calendar.ZONE_OFFSET))); // in hours
//System.out.println("DST_OFFSET: "
// + (c.get(Calendar.DST_OFFSET))); // in hours
System.out.println("***********************");
System.out.println(parse(c));
}*/
}

742
Modules/mbox/ZZMbox.java Normal file
View File

@@ -0,0 +1,742 @@
/*
ZZMbox.java
*
* Copyright (c) 2000, Ted Nelson, Tuomas Lukka and Vesa Parkkinen
*
* 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 Vesa Parkkinen
*/
package org.gzigzag.module;
import org.gzigzag.*;
import java.util.*;
import java.text.*; // DateFormat
import java.io.*;
import java.awt.*;
import gnu.regexp.*;
/** A mailbox file reader.
* <p>
* AAAAAAAARGGGGGGGGGGHHHHH!!!!!! How to do 8-bit cleanliness and
* internationalization correctly? It's still just a stream of bytes
* that we have underneath. Should probably use encoding when converting
* bytescroll stuff to strings. Gnnnh...
* <p>
* The way to test this is:
* <ul> <li> Put a path to the mbox to a cell, put right-hand cursor in it and
* execute ZZMbox.READMBOX
* </ul>
* <P>
* TODO: <ul><li>put all headers somewhere (sorted)</li>
* <li>more ways to connect messages (references?)</li>
* <li>smart way to move in threads </li>
* </ul>
*/
public class ZZMbox {
public static final String rcsid = "$Id: ZZMbox.java,v 1.32 2000/11/06 12:06:17 ajk Exp $";
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); }
static ZZCell byDate;
static ZZCell bySender;
static ZZCell bySubject;
static ZZCell byId;
static Hashtable hash = new Hashtable();
static public ZZModule module = new ZZModule() {
public void action(String id, ZZCell code,
ZZCell target,
ZZView v, ZZView cv,
String key, Point pt,
ZZScene xi) {
try {
ZZCell viewCell = v.getViewcell();
ZZCell viewCursor = ZZCursorReal.get(viewCell);
p("ZZMbox ACTION!");
if(id.equals("CREATEFLOBWINDOW")) {
// paths are:
//
// Date:
// handle -> Date: (d.handle)
// headcell(d.clone, -1)
// d.order +1
//
// From: same
// Subject: same
String[] fields = new String[] {
"Subject", "From", "Date", "ARDate"
};
ZZCell mli = viewCell.getHomeCell().N("d.2", 1);
mli.setText("MailflobDims");
ZZCell dlc = mli.N("d.1", 1);
ZZCell odlc = dlc;
ZZCell[] flobdims = new ZZCell[fields.length];
for(int i=0; i<fields.length; i++) {
if(i!=0)
dlc = dlc.N("d.2", 1);
dlc.setText(fields[i]);
flobdims[i] = dlc;
ZZCell path0 = dlc.N("d.1", 1);
ZZCell path1 = path0.N("d.1", 1);
path0 = ZZUtil.appendCommand(path0, new Object[]
{ "FIND", "d.handle", "1", fields[i]+":" });
path0 = ZZUtil.appendCommand(path0, new Object[]
{ "STEP", "d.1", "1"} );
path0 = ZZUtil.appendCommand(path0, new Object[]
{ "HEAD", "d.clone", "-1"} );
path0 = ZZUtil.appendCommand(path0, new Object[]
{ "STEP", "d.order", "1"} );
path1 = ZZUtil.appendCommand(path1, new Object[]
{ "FIND", "d.handle", "1", fields[i]+":" });
path1 = ZZUtil.appendCommand(path1, new Object[]
{ "STEP", "d.1", "1"} );
path1 = ZZUtil.appendCommand(path1, new Object[]
{ "HEAD", "d.clone", "-1"} );
}
mli = mli.N("d.2", 1);
mli.setText("MailSingleRasters");
ZZCell om = mli.N("d.1", 1);
om.setText("Single message");
{
ZZCell om1 = om.N("d.1", 1);
om1.setText("ZZMbox.onemsg");
}
mli = mli.N("d.2", 1);
mli.setText("MailflobRasters");
ZZCell fl = mli.N("d.1", 1);
fl.setText("Message space");
{
ZZCell fl1 = fl.N("d.1", 1);
fl1.setText("SimpleFlobRaster");
ZZCell dec = fl1.N("d.1",1).N("d.2",1);
dec.setText("decorator");
dec = dec.N("d.1", 1);
dec.setText("Something");
dec = dec.N("d.1", 1);
dec.setText("SimpleFlobConnector");
dec= dec.N("d.1", 1);
dec.setText("connection");
dec = dec.N("d.1",1);
dec = ZZUtil.appendCommand(dec, new Object[]
{ "FIND", "d.handle", "1", "In-Reply-To:" });
dec = ZZUtil.appendCommand(dec, new Object[]
{ "STEP", "d.1", "1"});
dec = ZZUtil.appendCommand(dec, new Object[]
{ "HEAD", "d.clone", "-1"});
dec = ZZUtil.appendCommand(dec, new Object[]
{ "STEP", "d.1", "-1"});
dec = ZZUtil.appendCommand(dec, new Object[]
{ "HEAD", "d.handle", "-1" });
}
// Moves in lock-step with normal param view.
ZZCell vc1 = ZZDefaultSpace.newToplevelView(
viewCell.getSpace(),
"mailflob",
0, 0, 500, 500,
fl, null, // XXX Defaultbind?
null, viewCell,
flobdims,
new Color(0x8080ff));
// One-message view
ZZCell vc2 = ZZDefaultSpace.newToplevelView(
viewCell.getSpace(),
"mailsingle",
500, 0, 500, 500,
om, null, // XXX Defaultbind?
null, viewCell,
null,
new Color(0x101020));
} else if(id.equals("READMBOX")) {
StringScroll scr = code.getSpace().getStringScroll("mbox");
byte[] barr;
String mbox_path = target.getText();
p("" + mbox_path);
RandomAccessFile f =
new RandomAccessFile(mbox_path,
"rw");
int l = (int)f.length();
barr = new byte[l];
int got;
if((got=f.read(barr, 0, barr.length)) < l){
throw new ZZError("Not enough data!" +got);
}
String s = new String(barr, "ISO8859_1");
//pa("S = " + s);
long addr = scr.append(s);
long addr2 = scr.curEnd()-1;
ZZCell c = target.N( "d.1", 1 );
byId = target.N( "d.2", 1 );
byId.setText("by id");
byId = byId.N("d.1", 1);
byDate = target.N( "d.2", 1 );
byDate.setText("by date");
byDate = byDate.N("d.1", 1);
bySubject = target.N( "d.2", 1 );
bySubject.setText("by subject");
bySubject = bySubject.N("d.1", 1);
bySender = target.N( "d.2", 1 );
bySender.setText("by sender");
bySender = bySender.N("d.1", 1);
c = c.N("d.1", 1);
c = c.N("d.1", 1);
c.setText("s1");
parse(scr, c);
} else {
pa("UNKNOWN ZZMBOX COMMAND "+id);
}
} catch(Exception e) {
e.printStackTrace();
throw new ZZError(""+e);
}
}
public ZOb newZOb(String id) {
if(id.equals("onemsg"))
return new org.gzigzag.module.mbox.SingleMail();
return null;
}
};
static RE startws;
static RE startfrom;
static RE iline;
static RE hdrline;
public static void sort(){
// let's use standard sort
ZZUtil.Comparator cmp = new ZZUtil.Comparator() {
public int compare(ZZCell c1, ZZCell c2 ){
// check for nulls. Necessary?
if ( c1 == null && c2 == null )
return 0;
if ( c1 == null )
return 1;
if ( c2 == null )
return -1;
//pa("c1 = " + c1.getText() + " c2 = " + c2.getText());
int ret = c1.getText().compareTo(c2.getText());
//pa("RET = " + ret );
return ret;
}
};
ZZUtil.sortRank(bySender, "d.byfield", 1, cmp, false, true );
ZZUtil.sortRank(bySubject, "d.byfield", 1, cmp, false, true );
ZZUtil.sortRank(byDate, "d.byfield", 1, new ZZUtil.Comparator() {
public int compare(ZZCell c1, ZZCell c2 ){
// check for nulls. Necessary?
/*
if ( c1 == null && c2 == null )
return 0;
if ( c1 == null )
return 1;
if ( c2 == null )
return -1;
*/
//pa("c1 = " + c1.getText() + " c2 = " + c2.getText());
SimpleDateFormat df = new SimpleDateFormat();
Date d1;
Date d2;
try {
d1 = df.parse(c1.getText());
d2 = df.parse(c2.getText());
} catch ( ParseException pe ) {
pa("EX: " + pe);
return 1;
}
//pa("" + d1 + " & " + d2);
if ( d1.equals(d2) )
return 0;
if ( d1.before(d2) )
return -1;
//if ( d1.after(d2) )
else return 1;
}
}, false, true);
}
public static void parse(final StringScroll scr, final ZZCell start) {
// Yes, I know this is strange, bordering
// on bizarre - rearrangement pending.
(new Runnable() {
long offs=0;
ZZCell lastCell = start;
Hashtable ids = new Hashtable();
String getLine() throws Exception {
// ARGH.. encoding real bad.
p("getline "+scr.curEnd()+" "+
offs);
int ind=-1;
if(offs==scr.curEnd()) return null;
String s = null;
for(int i=100; ind<0 && i<scr.curEnd()-offs; i+=100) {
if(offs+i >= scr.curEnd()) {
i = (int)(scr.curEnd()-offs-1);
}
s = scr.getString(offs, i);
ind = s.indexOf('\n');
}
if(ind<0 && offs != scr.curEnd()) {
p("Problem: no newline at end!");
//return null;
s = scr.getString(offs, (int)scr.curEnd());
offs = scr.curEnd();
return s;
}
s = s.substring(0, ind); // nl not included
offs += ind+1;
return s;
}
long hlstart;
long hlend;
String getHdrLine() throws Exception {
//p("Gethdrline");
hlstart = offs;
long o0 = offs;
String s = getLine();
if(s.equals("")) { // Start of body
return null;
}
if(startws==null)
startws = new RE("^\\s");
if(startws.getMatch(s, 0, RE.REG_ANCHORINDEX)!=null) {
throw new ZZError("ARGH! Invalid header");
}
while(true) {
o0 = offs;
String extra = getLine();
if(startws.getMatch(extra, 0, RE.REG_ANCHORINDEX)
== null) break;
s += extra;
p("Hdrline reloop "+extra);
}
//p("Hdrline end "+s);
offs = o0;
hlend = offs-2;
return s;
}
boolean was_empty = false;
String getBodyLine() throws Exception {
p("Getbody");
long o0 = offs;
String s = getLine();
if( s == null ) return null;
if(startfrom==null)
startfrom =
new RE("^From (.+) (... ... .. ..:..:.. ....)(.*)");
if(startfrom.getMatch(s, 0, RE.REG_ANCHORINDEX)!=null &&
was_empty) {
p("GETBODY: END BODY " + s);
offs = o0;
return null;
}
p("GETBODYRET: "+s);
if ( s.equals("")){
was_empty = true;
} else {
was_empty = false;
}
return s;
}
Span sp(long offs, REMatch m, int i) {
return sp(offs, m.getSubStartIndex(i),
m.getSubEndIndex(i));
}
Span sp(long offs, long i1, long i2) {
return sp(i1+offs, i2+offs);
}
Span sp(long i1, long i2) {
return Span.create(Address.scrollOffs(scr, i1),
Address.scrollOffs(scr, i2));
}
void dohoriz(ZZCell c, long o, REMatch m, int n) {
for(int i=1; i<n+1; i++) {
c.setSpan(sp(o, m, i));
if(i<n-1)
c = c.N("d.1", 1);
}
}
void doMessage() throws Exception {
//long t0 = System.currentTimeMillis();
lastCell = lastCell.N("d.2", 1);
boolean received = false;
//Vector hcells = new Vector();
//ZZCell cur = lastCell.N("d.handle", 1);
ZZCell cur = lastCell;
/*
Date previous;
Date broken;
ZZCell bCell;
*/
long o0 = offs; // beginning offset.
String s = getLine();
if(iline==null)
iline = new RE("^(From) (.*)");
REMatch m = iline.getMatch(s, 0, RE.REG_ANCHORINDEX);
//dohoriz(cur, o0, m, 2);
String h;
ZZCell fullhdr = cur;
long soffs = o0;
long eoffs = soffs;
ZZCell ar = null;
String irt = null;
while((h=getHdrLine())!=null) {
ZZCell ptr;
if(hdrline == null)
hdrline = new RE("^(\\S+):(.*)");
m = hdrline.getMatch(h, 0, RE.REG_ANCHORINDEX);
if(m==null) throw new ZZError("Inv hdr line "+h);
String hid = m.toString(1);
int poffs = m.getSubStartIndex(2);
String hparm = m.toString(2);
//p("MATCH: '"+hid+"' '"+poffs+"' '"+hparm+"'");
eoffs = offs;
if( ! hid.equals("Date") &&
! hid.equals("From") &&
! hid.equals("Received") &&
! hid.equalsIgnoreCase("Message-Id") &&
! hid.equals("In-Reply-To") &&
! hid.equals("References") &&
! hid.equals("Subject") )
{
continue;
}
//fullhdr = fullhdr.N("d.headers", 1);
ptr = fullhdr;
if( hid.equals("Subject") ){
//bySubject.insert("d.byfield",1,hval);
cur = cur.N("d.handle", 1);
cur.setText("Subject:");
ar = cur.N("d.1", 1);
ar.setText(hparm);
bySubject.insert("d.byfield",1,ar);
}
else if( hid.equals("From") ){
cur = cur.N("d.handle", 1);
cur.setText("From:");
ar = cur.N("d.1", 1);
int idx = 0;
hparm = hparm.replace('"', ' ');
//hparm = hparm.trim();
ar.setText(hparm.trim());
bySender.insert("d.byfield",1,ar);
}
else if( hid.equals("Date") ) {
//hval = hval.N("d.1", 1);
cur = cur.N("d.handle", 1);
//fullhdr.insert("d.headers", 1, cur);
//ptr = cur;
//ptr.setText("Assumed-Received:");
cur.setText("Date:");
ar = cur.N("d.1", 1);
try{
Calendar c =
ZZDateParser.parse(hparm);
Date d = c.getTime();
ar.setText(new SimpleDateFormat().format(d));
}
catch (NumberFormatException nfe){
pa("Not a rfc822 date! Fix it !");
ar.setText(hparm);
ar = ar.N("d.1", 1);
ar.setText("not RFC822 compliant");
}
//hash.put(d, hval);
byDate.insert("d.byfield", 1, ar);
}
else if( hid.equalsIgnoreCase("Message-Id")) {
String mi = hparm.trim();
p("Id: " + mi);
ZZCell t = byId;
cur = cur.N("d.handle", 1);
cur.setText("Message-Id:");
ar = cur.N("d.1", 1);
byId.insert("d.byfield", 1, ar);
ar.setText(mi);
ZZCell old = (ZZCell)ids.get(mi);
if ( old != null ){
// there must be a link to this
ZZCell clone = old.s("d.clone",1);
old.excise("d.clone");
if ( clone != null )
ar.insert("d.clone", 1, clone);
old.excise("d.byfield");
ids.remove(mi);
}
ids.put(mi, ar);
}
else if( hid.equals("In-Reply-To")) {
if ( irt != null)
pa("REFERENCES USED AND NOW I-R-T ");
irt = hparm;
//p("IRT = " + irt );
try {
irt = irt.substring(irt.lastIndexOf('<'),
irt.lastIndexOf('>')+1);
}
catch( StringIndexOutOfBoundsException e ){
//irt = hparm;
//pa("NOT VALID: " + hparm);
irt = "";
}
if (! irt.equals("") ){
cur = cur.N("d.handle", 1);
cur.setText("In-Reply-To:");
ar = cur.N("d.1", 1);
ZZCell tmp = byId;
ZZCell repliedTo = (ZZCell)ids.get(irt);
if ( repliedTo == null ){
//create empty cell
//pa("REPLIED MESSAGE NOT IN HASH");
repliedTo = byId.N("d.byfield", 1);
repliedTo.setText(irt);
ar.setText(irt);
ids.put(irt, repliedTo);
}
repliedTo.insert("d.clone", 1, ar);
}
}
else if( hid.equals("References")) {
// if no i-r-t
if ( irt != null ){
irt = hparm;
//p("IRT = " + irt );
try {
irt = irt.substring(irt.lastIndexOf('<'),
irt.lastIndexOf('>')+1);
}
catch( StringIndexOutOfBoundsException e ){
//irt = hparm;
//pa("NOT VALID: " + hparm);
irt = "";
}
if (! irt.equals("") ){
cur = cur.N("d.handle", 1);
cur.setText("In-Reply-To:");
ar = cur.N("d.1", 1);
ZZCell tmp = byId;
ZZCell repliedTo = (ZZCell)ids.get(irt);
if ( repliedTo == null ){
//create empty cell
//pa("REPLIED MESSAGE NOT IN HASH");
repliedTo = byId.N("d.byfield", 1);
repliedTo.setText(irt);
ar.setText(irt);
ids.put(irt, repliedTo);
}
repliedTo.insert("d.clone", 1, ar);
}
}
}
else if( hid.equals("Received" ) && ! received ){
cur = cur.N("d.handle", 1);
cur.setText("ARDate:");
ar = cur.N("d.1", 1);
String dar = hparm;
dar = dar.substring(dar.indexOf(";")+1,
dar.length());
try{
Calendar c =
ZZDateParser.parse(dar);
Date d = c.getTime();
//ar.setText(d.toString());
ar.setText(new SimpleDateFormat().format(d));
}
catch (NumberFormatException nfe){
pa("Not a rfc822 date!");
// XXX interpolate
ar.setText(dar);
ar = ar.N("d.1", 1);
ar.setText("not RFC822 compliant");
}
received = true;
}
}
ZZCell head = fullhdr.N( "d.headers", 1);
head.setSpan(sp(soffs, eoffs-1));
// Finally, handle skewers the body as well.
String b;
long bod = offs;
while((b=getBodyLine())!=null) {
}
cur = cur.N("d.handle",1);
cur.setSpan(sp(bod, offs));
//hcells.addElement(cur);
//pa("TIME USED = " + (System.currentTimeMillis() - t0) );
}
public void run() {
try {
while(offs < scr.curEnd()) {
doMessage();
}
} catch(Exception e) {
p(""+e);
e.printStackTrace();
}
sort();
float date_float = 0;
float subj_float = 0;
float from_float = 0;
ZZCell c = byDate.h("d.byfield" ,-1);
if ( c != null) {
int length = c.getRankLength("d.byfield")-1;
//pa("LENGTH = " + length);
c = c.s("d.byfield", 1);
for(int i = 0; i < length; i++){
c.N("d.order", 1).setText("" + date_float);
date_float += 1.0/length;
c = c.s("d.byfield", 1);
}
}
c = bySubject.h("d.byfield" ,-1);
if ( c != null) {
int length = c.getRankLength("d.byfield") -1;
//pa("LENGTH = " + length);
c = c.s("d.byfield", 1);
for(int i = 0; i < length; i++){
c.N("d.order", 1).setText("" + subj_float);
subj_float = subj_float + ((float)1)/length;
//p("subj_float = " + subj_float );
c = c.s("d.byfield", 1);
}
}
c = bySender.h("d.byfield" ,-1);
if ( c != null) {
int length = c.getRankLength("d.byfield") -1;
//pa("LENGTH = " + length);
c = c.s("d.byfield", 1);
for(int i = 0; i < length; i++){
c.N("d.order", 1).setText("" + from_float);
from_float += 1.0/length;
c = c.s("d.byfield", 1);
}
}
}
}).run();
}
}

191
Modules/mind/Mind.java Normal file
View File

@@ -0,0 +1,191 @@
/*
* Mind.java
*
* @author asko.soukka@iki.fi
* @version 0.1
*
* Copyright (c) 2002 Asko Soukka
* GZigZag is written by Tuomas Lukka
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* See the LICENSE.lgpl for the specific terms of the license.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*/
/*
* Written by Asko Soukka and Tuukka Hastrup
*/
package org.gzigzag.module;
import org.gzigzag.*;
import java.util.*;
import java.io.*;
import java.awt.*;
/** Mindmap tools from Asko Soukka for mainly hierarcical structures
*/
public class Mind {
public static final String rcsid = "$Id: Mind.java,v 1.1.2.2 2002/02/16 15:46:58 tuukkah Exp $";
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); }
static public ZZModule module = new ZZModule() {
public ZOb newZOb(String id) {
if(id.equals("Sundew"))
return new MindSundew();
else if(id.equals("Sun"))
return new MindSun();
return null;
}
public void action(String id, ZZCell code,
ZZCell target,
ZZView v, ZZView cv,
String key, Point pt,
ZZScene xi) {
try {
ZZCell viewCell = v.getViewcell();
ZZCell viewCursor = ZZCursorReal.get(viewCell);
if(id.equals("TextOut")) {
FileWriter fileout = new FileWriter(target.getText() + ".txt");
BufferedWriter writer = new BufferedWriter(fileout);
writer.write(target.getText()+"\n");
if (target.s("d.1", 1) != null) {
writer.write("\n");
printTextTree("d.2", "d.1", target.s("d.1", 1), writer,
1, 10);
writer.write("\n");
}
writer.close();
} else if(id.equals("HtmlOut")) {
FileWriter fileout = new FileWriter(target.getText()+".html");
BufferedWriter writer = new BufferedWriter(fileout);
writer.write("<html>\n");
writer.write("<head><title>\n");
writer.write(target.getText()+"\n");
writer.write("</title></head>\n");
writer.write("<body>\n");
writer.write("<h1>" + target.getText() + "</h1>\n");
if (target.s("d.1", 1) != null) {
writer.write("\n");
printHtmlTree("d.2", "d.1", "d.clone", target.s("d.1", 1),
writer, 1, 10, 2);
writer.write("\n");
}
writer.write("</body>\n");
writer.write("</html>\n");
writer.close();
} else {
pa("UNKNOWN Mind COMMAND "+id);
}
} catch(Exception e) {
e.printStackTrace();
throw new ZZError(""+e);
}
}
};
private static void printTextTree(String dim, String dimTop, ZZCell accursed,
BufferedWriter writer, int start, int end) {
Vector cells = getAllCells(dim, accursed);
int i = 0;
try {
while (i < cells.size()) {
if (!((ZZCell)cells.elementAt(i)).getText().equals("")) {
writer.write(/*"<li>"+*/((ZZCell)cells.elementAt(i)).getText()+"\n");
}
if (((ZZCell)cells.elementAt(i)).s(dimTop, 1) != null) {
for (int j=0; j<start; j++) writer.write("-"); writer.write("\n");
if(start < end) printTextTree(dim, dimTop, ((ZZCell)cells.elementAt(i)).s(dimTop, 1), writer,
start + 1, end);
writer.write("\n");
}
i++;
}
} catch (IOException iOE) {}
}
private static void printHtmlTree(String dim, String dimTop, String dimLink,
ZZCell accursed, BufferedWriter writer,
int start, int end, int topics) {
Vector cells = getAllCells(dim, accursed);
int i = 0;
try {
if (start > topics) writer.write("<ul>\n");
while (i < cells.size()) {
if (!((ZZCell)cells.elementAt(i)).getText().equals("")) {
if (start > topics) {
writer.write("<li>");
if (((ZZCell)cells.elementAt(i)).s(dimLink, -1) == null) {
if (((ZZCell)cells.elementAt(i)).s(dimLink, 1) != null)
writer.write("<a name=\""+((ZZCell)cells.elementAt(i)).getText()+"\"></a>");
writer.write(((ZZCell)cells.elementAt(i)).getText());
} else {
writer.write("<a href=\"#"+((ZZCell)cells.elementAt(i)).getText()+"\">");
writer.write(((ZZCell)cells.elementAt(i)).getText()+"</a>");
}
writer.write("\n");
} else {
writer.write("<h"+start+">");
if (((ZZCell)cells.elementAt(i)).s(dimLink, -1) == null) {
if (((ZZCell)cells.elementAt(i)).s(dimLink, 1) != null)
writer.write("<a name=\""+((ZZCell)cells.elementAt(i)).getText()+"\"></a>");
writer.write(((ZZCell)cells.elementAt(i)).getText());
} else {
writer.write("<a href=\"#"+((ZZCell)cells.elementAt(i)).getText()+"\">");
writer.write(((ZZCell)cells.elementAt(i)).getText()+"</a>");
}
writer.write("</h"+start+">\n");
}
}
if (((ZZCell)cells.elementAt(i)).s(dimTop, 1) != null) {
writer.write("\n");
if(start < end) printHtmlTree(dim, dimTop, dimLink, ((ZZCell)cells.elementAt(i)).s(dimTop, 1), writer,
start + 1, end, topics);
writer.write("\n");
}
i++;
}
if (start > topics) writer.write("</ul>\n");
} catch (IOException iOE) {}
}
private static Vector getAllCells(String dim, ZZCell accursed) {
int LIMIT = 1000;
Vector cells = new Vector();
ZZCell next = null;
cells.addElement(accursed);
int i = 1;
while (cells.size() < LIMIT ) {
next = accursed.s(dim, i++);
if(next != null && !cells.contains(next)) cells.addElement(next);
else break;
}
return cells;
}
}

398
Modules/mind/MindSun.java Normal file
View File

@@ -0,0 +1,398 @@
/*
* MindSun.java
*
* A View for GZZ 0.6.X.
*
* @author asko.soukka@iki.fi
* @version 0.1
*
* I was not satisfied with MindSundiew view. It wasted too much space
* and still did not show enough information. So, I dropped using full circles.
* Still this view is optimized for cyclic structures.
*
* Copyright (c) 2002 Asko Soukka
* Contains a few parts of CompassView.java (c) 2002 Tuukka Hastrup
* GZigZag is written by Tuomas Lukka
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* See the LICENSE.lgpl for the specific terms of the license.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*/
/*
To do:
Commenting code :) (javadoc-spesific)
*/
package org.gzigzag.module;
import org.gzigzag.*;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Point;
import java.lang.Math;
import java.util.Vector;
class MindSun implements FlobView, ZOb {
/** */
public static final String rcsid = "$Id: MindSun.java,v 1.1.2.3 2002/02/16 16:33:06 tuukkah Exp $";
public MindSun() {}
/**
* @param
*/
public String readParams(ZZCell c) { return null; };
/**
* @param
* @param
* @param
* @param
* @param
*/
public void raster(FlobSet into, FlobFactory fact, ZZCell view,
String[] dims, ZZCell accursed) {
/** */
Dimension d = into.getSize();
int midx = d.width / 2;
int midy = d.height / 2;
int r = d.width / 5;
/** */
ZZUtil.showFlobDims(into, fact, view, 3);
/** */
Vector cells = getAllCells(dims[1], accursed);
if (cells.size() > 0) {
drawCircle(midx, midy, into, fact, dims[1], cells, r, 1, false);
drawTopCurves(midx, midy, into, fact, dims, cells, r, 1.95 * Math.PI, 2, 4, true);
drawSubCurves(midx, midy, into, fact, dims, cells, r, 0.95 * Math.PI, 2.95 * Math.PI, 2, 3, true);
/** */
Dimension c = fact.getSize(null, 1);
int cw = c.width;
int ch = c.height;
for (int i = 1; i < 4; i++) {
if (accursed.s(dims[2], -i) != null) {
fact.makeFlob(into, accursed.s(dims[2], -i), accursed.s(dims[2], -i),
(float)0.75, midx + x(1.95 * Math.PI, r)-cw/2, midy+y(1.95 * Math.PI, r)-ch/2*(i+1), i+1,
(int)(cw * 0.75), (int)(ch * 0.75));
}
if (accursed.s(dims[2], i) != null) {
fact.makeFlob(into, accursed.s(dims[2], i), accursed.s(dims[2], i),
(float)0.75, midx + x(1.95 * Math.PI, r)-cw/2, midy+y(1.95 * Math.PI, r)-ch/3+ch/2*i, i+1,
(int)(cw * 0.75), (int)(ch * 0.75));
}
}
}
}
/**
* @param
* @param
*/
private Vector getAllCells(String dim, ZZCell accursed) {
/** */
int LIMIT = 20;
/** */
Vector cells = new Vector();
/** */
ZZCell next = null;
/** */
cells.addElement(accursed);
/** */
int i = 1;
do {
if (cells.size() > LIMIT / 2) break;
next = accursed.s(dim, i++);
if(next != null && !cells.contains(next)) cells.addElement(next);
else break;
} while (true);
/** */
i = -1;
do {
if (i < -LIMIT / 2) break;
next = accursed.s(dim, i--);
} while (next != null && !cells.contains(next));
/** */
if (next != accursed) {
i += 2;
do {
if (cells.size() > LIMIT) break;
next = accursed.s(dim, i++);
if(next != null && !cells.contains(next)) cells.addElement(next);
else break;
} while (true);
}
/** */
return cells;
}
/**
* @param
* @param
* @param
* @param
* @param
* @param
* @param
* @param
*/
private void drawTopCurves(int midx, int midy, FlobSet into, FlobFactory fact, String[] dims, Vector cells,
int r, double angle, int startLevel, int endLevel, boolean vanishing) {
/** */
float factor = (float) (-Math.log(startLevel) / (-Math.log(startLevel)+2.7) + 1);
/** */
double angleStep = 2 * Math.PI / cells.size();
/** */
for (int i=0; i<cells.size(); i++) {
if (((ZZCell)cells.elementAt(i)).s(dims[0], -1) != null) {
Vector subCells = getAllCells(dims[1], ((ZZCell)cells.elementAt(i)).s(dims[0], -1));
drawCurve(midx, midy, into, fact, subCells, angle - angleStep / 2, angle + angleStep / 2,
(int)(r * factor), startLevel, true);
/** */
if (startLevel < endLevel)
drawTopCurves(midx, midy, into, fact, dims, subCells, r, angle,
startLevel + 1, endLevel, true);
}
/** */
angle += angleStep;
}
}
/**
* @param
* @param
* @param
* @param
* @param
* @param
* @param
* @param
*/
private void drawSubCurves(int midx, int midy, FlobSet into, FlobFactory fact, String[] dims, Vector cells,
int r, double startAngle, double endAngle, int startLevel, int endLevel, boolean vanishing) {
/** */
float factor = (float)Math.log(startLevel)+1;
/** */
double angle = startAngle + (endAngle - startAngle) / 2;
ZZCell backup = null;
/** */
if (cells.elementAt(0) != null && ((ZZCell)cells.elementAt(0)).getText().equals("") && startLevel != 2) {
backup = (ZZCell)cells.elementAt(0);
cells.removeElementAt(0);
}
/** */
double angleStep;
if (cells.size()%2 == 0 && startLevel != 2) angleStep = (endAngle - startAngle) / (cells.size() + 1);
else angleStep = (endAngle - startAngle) / cells.size();
/** */
for (int i=0; i<cells.size(); i++) {
if (((ZZCell)cells.elementAt(i)).s(dims[0], 1) != null) {
Vector subCells = getAllCells(dims[1], ((ZZCell)cells.elementAt(i)).s(dims[0], 1));
drawCurve(midx, midy, into, fact, subCells, angle - angleStep/2 + 0.05 * (1/factor),
angle + angleStep/2 - 0.05 * (1/factor), (int)(r * factor), startLevel, true);
/** */
if (startLevel < endLevel)
drawSubCurves(midx, midy, into, fact, dims, subCells, r,
angle - angleStep/2, angle + angleStep/2,
startLevel+1, endLevel, true);
}
/** */
angle += angleStep;
if (cells.size()%2 == 0 && angle >= endAngle - angleStep / 3 * 2
|| cells.size()%2 != 0 && angle >= endAngle)
angle = (startAngle + (endAngle - startAngle) / 2) - (cells.size() - (i + 1)) * angleStep;
}
/** */
if (backup != null) cells.insertElementAt(backup, 0);
}
/**
* @param
* @param
* @param
* @param
* @param
* @param
* @param
* @param
*/
private void drawCurve(int midx, int midy, FlobSet into, FlobFactory fact, Vector cells,
double startAngle, double endAngle, int r, int level, boolean vanishing) {
/** */
Dimension c = fact.getSize(null, 1);
int cw = c.width;
int ch = c.height;
/** */
double angle = startAngle + (endAngle - startAngle) / 2;
/** */
int i = 0;
ZZCell backup = null;
/** */
if (cells.elementAt(0) != null && ((ZZCell)cells.elementAt(0)).getText().equals("")) {
int dx = x(angle, r-cw/8);
int dy = y(angle, r-cw/8);
float factor = (float)-Math.log(level)/4+1;
fact.makeFlob(into, (ZZCell)cells.elementAt(i), (ZZCell)cells.elementAt(i),
factor, midx + dx-cw/2, midy+dy-ch/2, level+2, (int)(cw * factor), (int)(ch * factor));
backup = (ZZCell)cells.elementAt(0);
cells.removeElementAt(0);
}
/** */
double angleStep;
if (cells.size()%2 == 0) angleStep = (endAngle - startAngle) / (cells.size() + 1);
else angleStep = (endAngle - startAngle) / cells.size();
/** */
while (i < cells.size()) {
int dx = x(angle, r);
int dy = y(angle, r);
/** */
float factor;
if (i == 0) factor = (float)(-Math.log(level)/4+1.1);
else factor = (float)-Math.log(level)/4+1;
if(cells.elementAt(i) != null)
fact.makeFlob(into, (ZZCell)cells.elementAt(i), (ZZCell)cells.elementAt(i),
factor, midx + dx-cw/2, midy+dy-ch/2, level, (int)(cw * factor), (int)(ch * factor));
/** */
if (vanishing) {
if (i < cells.size() / 2) level ++;
else if (i > cells.size() / 2) level --;
}
i++;
/** */
angle += angleStep;
if (cells.size()%2 == 0 && angle >= endAngle - angleStep / 3 * 2
|| cells.size()%2 != 0 && angle >= endAngle)
angle = (startAngle + (endAngle - startAngle) / 2) - (cells.size() - i) * angleStep;
}
/** */
if (backup != null) cells.insertElementAt(backup, 0);
}
/**
* @param
* @param
* @param
* @param
* @param
* @param
* @param
* @param
*/
private void drawCircle(int midx, int midy, FlobSet into, FlobFactory fact, String dim, Vector cells,
int r, int level, boolean vanishing) {
/** */
LineDecor.Builder line = new LineDecor.Builder(into, Color.red);
line.startl(4, 1);
/** */
Dimension c = fact.getSize(null, 1);
int cw = c.width;
int ch = c.height;
/** */
double angleStep = 2 * Math.PI / cells.size();
double angle = (double) 1.95 * Math.PI;
/** */
int i = 0;
while (i < cells.size()) {
int dx = x(angle, r);
int dy = y(angle, r);
/** */
float factor = (float)-Math.log(level)/4+1;
if(cells.elementAt(i) != null)
/* fact.centerFlob(into, (ZZCell)cells.elementAt(i), (ZZCell)cells.elementAt(i),
factor, new Point(midx + dx-cw/2, midy+dy-ch/2), 0, 0, level);*/
fact.makeFlob(into, (ZZCell)cells.elementAt(i), (ZZCell)cells.elementAt(i),
factor, midx + dx-cw/2, midy+dy-ch/2, level, (int)(cw * factor), (int)(ch * factor));
/** */
if (vanishing) {
if (i < cells.size() / 2) level ++;
else if (i > cells.size() / 2) level --;
}
/** */
angle += angleStep;
/** */
if (cells.elementAt(i)!=null && cells.size() > 1) {
if (((ZZCell)cells.elementAt(i)).s(dim, 1) == null) {
line.l(midx+x(angle - angleStep / 2 - 0.01, r-ch)-cw/2, midy+y(angle - angleStep / 2 - 0.01, r-ch)-ch/2,
midx+x(angle - angleStep / 2 - 0.01, r+ch)-cw/2, midy+y(angle - angleStep / 2 - 0.01, r+ch)-ch/2);
line.l(midx+x(angle - angleStep / 2 + 0.01, r-ch)-cw/2, midy+y(angle - angleStep / 2 + 0.01, r-ch)-ch/2,
midx+x(angle - angleStep / 2 + 0.01, r+ch)-cw/2, midy+y(angle - angleStep / 2 + 0.01, r+ch)-ch/2);
}
else if (i < cells.size() - 1) {
if (((ZZCell)cells.elementAt(i)).s(dim, 1) != (ZZCell)cells.elementAt(i+1))
line.l(midx+x(angle - angleStep / 2, r-ch)-cw/2, midy+y(angle - angleStep / 2, r-ch)-ch/2,
midx+x(angle - angleStep / 2, r+ch)-cw/2, midy+y(angle - angleStep / 2, r+ch)-ch/2);
} else {
if (((ZZCell)cells.elementAt(i)).s(dim, 1) != (ZZCell)cells.elementAt(0)) {
line.l(midx+x(angle - angleStep / 2, r-ch)-cw/2, midy+y(angle - angleStep / 2, r-ch)-ch/2,
midx+x(angle - angleStep / 2, r+ch)-cw/2, midy+y(angle - angleStep / 2, r+ch)-ch/2);
line.l(midx+x(angle - angleStep / 2 + 0.01, r-ch)-cw/2, midy+y(angle - angleStep / 2 + 0.01, r-ch)-ch/2,
midx+x(angle - angleStep / 2 + 0.01, r+ch)-cw/2, midy+y(angle - angleStep / 2 + 0.01, r+ch)-ch/2);
}
}
}
/** */
i++;
}
/** */
line.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);
}
}

View File

@@ -0,0 +1,247 @@
/*
* MindSundew.java
*
* Ajatuskihokkipurkkaviritys GZZ 0.6.X:lle.
* Mindmap scribble for GZigZag 0.6.X.
*
* @author asko.soukka@iki.fi
*
* Copyright (C) 2001 Asko Soukka, based on CompassView.java by Tuukka Hastrup
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* See the LICENSE.lgpl for the specific terms of the license.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*/
package org.gzigzag.module;
import 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;
class MindSundew implements FlobView, ZOb {
public static final String rcsid = "$Id: MindSundew.java,v 1.1.2.1 2002/02/16 15:19:25 tuukkah Exp $";
private int level = 0;
private int levelA = 0;
private int levelB = 0;
public MindSundew() {}
public String readParams(ZZCell c) { return null; };
public void raster(FlobSet into, FlobFactory fact, ZZCell view,
String[] dims, ZZCell accursed) {
/* ---- alustetaan kaikenlaista ---- */
// FlobDecorator linker = new StdLinks();
ZZCell stdim = ZZCursorReal.get(view.s("d.dims", 1));
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;
ZZUtil.showFlobDims(into, fact, view, 3);
/* ---------------------------------------------------- */
/* ---- piirretään ulottuvuuksien värit ylänurkkaan ---- */
LineDecor.Builder line1 = new LineDecor.Builder(into, Color.black);
LineDecor.Builder line2 = new LineDecor.Builder(into, Color.gray);
LineDecor.Builder line3 = new LineDecor.Builder(into, Color.yellow);
line1.startl(4, 1);
line2.startl(4, 1);
line3.startl(4, 1);
line1.l(c.width/2, c.height/2, c.width*2, c.height/2);
line2.l(c.width/2, c.height/2, c.width/2, c.height*2);
line3.l(c.width/2, c.height/2, c.width*2, c.height*2);
line1.endl();
line2.endl();
line3.endl();
/* ---------------------------------------------------- */
/* ---- kutsutaan ensimmäistä piirtokierrosta ---- */
drawLevel(into, fact, dims, accursed, d, c, stdim, midx, midy, cw, ch);
//linker.decorate(into, "", view);
/* ---------------------------------------------------- */
}
private void drawLevel(FlobSet into, FlobFactory fact, String[] dims, ZZCell accursed,
Dimension d, Dimension c, ZZCell stdim, int midx, int midy, int cw, int ch) {
/* ---- asetetaan piirtokierroksen tasokohtaiset ---- */
level++;
float kerroin = 1; // käytetään solujen piirtokoossa
if (level > 1) {
kerroin = (float)0.7;
for (int i=2; i<level; i++)
kerroin = kerroin * kerroin;
}
/* ---------------------------------------------------- */
/* ---- alustetaan piirtokierroksen jutut ---- */
Vector cells = new Vector(); // Cells to positive directions to be drawn
ZZCell dim, tc, top;
top = null;
dim = stdim;
/* ---------------------------------------------------- */
/* ---- haetaan kierroksella piirrettävät solut ---- */
cells.addElement(accursed);
top = accursed.s(dims[0], -1);
int i = 1;
do {
tc = accursed.s(dims[1], i++);
if(tc != null && tc != accursed) {
cells.addElement(tc);
if (top == null) top = tc.s(dims[0], -1);
}
else break;
} while (true);
i = -1;
do { tc = accursed.s(dims[1], i--); } while (tc != null && tc != accursed);
if (tc == null) {
i += 2;
do {
tc = accursed.s(dims[1], i++);
if(tc != null && tc != accursed) {
cells.addElement(tc);
if (top == null) top = tc.s(dims[0], -1);
}
else break;
} while (true);
}
if(cells.size() == 0) return; // No cells to draw
/* ---------------------------------------------------- */
/* ---- ympyrän laskemiseen tarvittavia juttuja ---- */
double angle = 2 * Math.PI / (cells.size());
int l = (int) ((d.height < d.width ? d.height : d.width)
/ 2 * 0.47 * kerroin * kerroin ); // syvyystasojen etäisyys ja säde
double a = (double) 1.95 * Math.PI; // Begin placing positive cells top left
/* ---------------------------------------------------- */
/* ---- viivapiirtureiden alustus ---- */
LineDecor.Builder line1 = new LineDecor.Builder(into, Color.black);
LineDecor.Builder line2 = new LineDecor.Builder(into, Color.gray);
LineDecor.Builder line3 = new LineDecor.Builder(into, Color.yellow);
line1.startl(cells.size()*4, 12);
line2.startl(cells.size()*4, 12);
line3.startl(cells.size()*4, 12);
/* ---------------------------------------------------- */
/* ---- solujen piirto ja uusien kierrosten käynnistys- */
i = 0;
while (i < cells.size()) {
int dx = x(a, l);
int dy = y(a, l);
if(cells.elementAt(i)!=null) {
/* // ensimmäinen yläkäsite piirretään isolla, muuta tasokohtaisesti
if (levelA == 1 && (ZZCell)cells.elementAt(i) == accursed)
fact.centerFlob(into, (ZZCell)cells.elementAt(i), (ZZCell)cells.elementAt(i),
(float)1.1, new java.awt.Point(midx + dx-cw/2, midy+dy-ch/2), 0, 0, 1);
else if (levelB != 1)
fact.centerFlob(into, (ZZCell)cells.elementAt(i), (ZZCell)cells.elementAt(i),
kerroin, new java.awt.Point(midx + dx-cw/2, midy+dy-ch/2), 0, 0, level * level);
else
fact.centerFlob(into, (ZZCell)cells.elementAt(i), (ZZCell)cells.elementAt(i),
kerroin, new java.awt.Point(midx + dx-cw/2, midy+dy-ch/2), 0, 0, level); */
// ensimmäinen yläkäsite piirretään isolla, muuta tasokohtaisesti
if (levelA == 1 && (ZZCell)cells.elementAt(i) == accursed)
fact.makeFlob(into, (ZZCell)cells.elementAt(i), (ZZCell)cells.elementAt(i),
(float)1.1, midx + dx-cw/2, midy+dy-ch/2, 1, cw, ch);
else if (levelB != 1)
fact.makeFlob(into, (ZZCell)cells.elementAt(i), (ZZCell)cells.elementAt(i),
kerroin, midx + dx-cw/2, midy+dy-ch/2, level*level, (int)(cw * kerroin), (int)(ch * kerroin));
else
fact.makeFlob(into, (ZZCell)cells.elementAt(i), (ZZCell)cells.elementAt(i),
kerroin, midx + dx-cw/2, midy+dy-ch/2, level, (int)(cw * kerroin), (int)(ch * kerroin));
// jos ei olla piirtämässä alakäsitteitä, käynnistetään piirto löydetylle yläkäsitteelle
if (((ZZCell)cells.elementAt(i)).s(dims[0], -1) == top
&& level < 3 && top != null && levelB == 0) {
levelA++;
line1.l(midx + dx-cw/2, midy+dy-ch/2, midx-cw/2, midy-ch/2);
drawLevel(into, fact, dims, top, d, c, stdim, midx, midy, cw, ch);
levelA--;
}
// jos ei olla piirtämässä yläkäsitteitä, käynnistetään piirto löydetylle alakäsitteelle
if (((ZZCell)cells.elementAt(i)).s(dims[0], 1) != null && level < 3 && levelA == 0) {
levelB++;
line1.l(midx + dx-cw/2, midy+dy-ch/2, (int)(midx + (dx)*(1/kerroin)*2/level-cw/2),
(int)(midy + (dy)*(1/kerroin)*2/level-ch/2));
if (level < 2)
drawLevel(into, fact, dims, ((ZZCell)cells.elementAt(i)).s(dims[0], 1), d, c, stdim,
(int)(midx + (dx)*(1/kerroin)*2/level), (int)(midy + (dy)*(1/kerroin)*2/level), cw, ch);
levelB--;
}
// käynnistetään piirto löydetylle sivuttaislinkitykselle
if ((ZZCell)cells.elementAt(i) == accursed &&
((ZZCell)cells.elementAt(i)).s(dims[2], -1) != null && level == 1) {
line3.l(midx + dx-cw/2, midy+dy-ch/2, (int)(d.width / 10)+cw+cw/8, (int)(d.height / 10));
// line3.l(midx + dx-cw/2, midy+dy-ch/2, (int)(d.width / 10)+cw/2, (int)(d.height / 10)+ch/2);
drawLevel(into, fact, dims, ((ZZCell)cells.elementAt(i)).s(dims[2], -1), d, c, stdim,
(int)(d.width / 10)+cw, (int)(d.height / 10)+ch, cw, ch);
}
if ((ZZCell)cells.elementAt(i) == accursed &&
((ZZCell)cells.elementAt(i)).s(dims[2], 1) != null && level == 1) {
line3.l(midx + dx-cw/2, midy+dy-ch/2, (int)(d.width * 9/10)+cw/4,
(int)(d.height * 9/10));
// line3.l(midx + dx-cw/2, midy+dy-ch/2, (int)(d.width * 9/10)-cw/2,
// (int)(d.height * 9/10)-ch/2);
drawLevel(into, fact, dims, ((ZZCell)cells.elementAt(i)).s(dims[2], 1), d, c, stdim,
(int)(d.width * 9/10), (int)(d.height * 9/10), cw, ch);
}
}
// siirrytään ympyrän kehällä eteenpäni
a += angle; // Rotate clockwise
// jos solusta on jatke eteenpäin (täytynee olla kehällä), piirretään viiva
if (cells.elementAt(i)!=null && levelB < 2)
if (((ZZCell)cells.elementAt(i)).s(dims[1], 1) != null)
line2.l(midx + dx-cw/2, midy+dy-ch/2, midx + x(a, l)-cw/2, midy+y(a, l)-ch/2);
// seuraava solu jonossa
i++;
}
/* ---------------------------------------------------- */
/* ---- piirtureiden lopetus ja tason lasku ----- */
line1.endl();
line2.endl();
line3.endl();
level--;
/* ---------------------------------------------------- */
}
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);
}
}

View File

@@ -0,0 +1,40 @@
/*
Default.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 Tero Mäyränen
*/
package org.gzigzag.module.multimedia;
import org.gzigzag.*;
import java.awt.*;
import java.awt.image.*;
public class Default extends MediaZOb
{
public static final String rcsid = "$Id: Default.java,v 1.3 2001/02/22 15:31:13 deetsay Exp $";
private Pixels pix = new Pixels(1, 1);
public Pixels getPixels()
{
pix.getPixels()[0] = 0xff000000;
return pix;
}
}

View File

@@ -0,0 +1,189 @@
/*
MediaFlobFactory.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 Tero Mäyränen
*/
package org.gzigzag.module.multimedia;
import org.gzigzag.*;
import java.awt.*;
import java.awt.image.*;
import java.util.*;
public class MediaFlobFactory extends Default implements FlobFactory
{
public static final String rcsid = "$Id: MediaFlobFactory.java,v 1.14 2001/02/27 08:42:42 raulir Exp $";
static private String flobText;
static private float flobFract;
static private Vector flobColors = new Vector();
static public String getFlobText() { return flobText; }
static public float getFlobFract() { return flobFract; }
static public Vector getFlobColors() { return flobColors; }
static private Hashtable mediaCache = new Hashtable();
static private ImageObserver imgobs = new ImageObserver() {
public boolean imageUpdate(Image i, int inf, int i2,
int i3, int i4, int i5) {
if ((inf & ALLBITS) != 0) {
ZZUpdateManager.chg();
return false;
}
return true;
}
};
/**
* Get cached MediaZOb for ZZCell or make a new MediaZOb and
* add it to the cache.
*
* @param c ZZCell whose corresponding MediaZOb we want
*/
private MediaZOb getFromCache(ZZCell c)
{
MediaZOb mz;
ZZCell rc = c.h("d.clone"); // Cache rootclones only
if (mediaCache.containsKey(rc))
{
mz = (MediaZOb)mediaCache.get(rc);
}
else
{
mz = MediaZOb.newMediaZOb(rc);
mediaCache.put(rc, mz);
}
return mz;
}
public Dimension getSize(ZZCell c, float fract)
{
if (c == null) return new Dimension
(
readParam("width").getInt(80), readParam("height").getInt(15)
);
flobText = c.getText();
MediaZOb mz = getFromCache(c);
// Image img = ScalableFont.fmComp.createImage(mz);
// return new Dimension(img.getWidth(null), img.getHeight(null));
Pixels pix = mz.getPixels();
if (pix.getWidth() < 0 || pix.getHeight() < 0) {
return new Dimension(0, 0);
}
return new Dimension(pix.getWidth(), pix.getHeight());
}
public Flob makeFlob(FlobSet into, ZZCell zzc, final ZZCell handleCell,
final float fract, int x, int y, int d, int w, int h)
{
Flob cf = new Flob(x, y, d, w, h, zzc)
{
public void renderInterp(Graphics g,float frac)
{
Flob r=interpTo;
if (r==null) return;
int mx=(int)(this.x+frac*(r.x-this.x)),
my=(int)(this.y+frac*(r.y-this.y)),
mw=(int)(this.w+frac*(r.w-this.w)),
mh=(int)(this.h+frac*(r.h-this.h));
g.drawRect(mx,my,mw-1,mh-1);
}
public void render(Graphics g, int mx, int my, int md, int mw, int mh)
{
if (!ZZDrawing.instance.qualityEnabled()) return;
flobColors.removeAllElements();
ZZCell orig = c.h("d.clone", -1);
if (orig.h("d.cursor-list", -1).s("d.cursor", -1) != null)
{
flobColors.addElement(ZZCursorReal.getColorOrWhite(orig));
}
else
{
Enumeration e = ZZCursorReal.getPointers(c);
while (e.hasMoreElements())
{
ZZCell cu = (ZZCell)e.nextElement();
Color color = ZZCursorReal.getColor(cu);
if (color != null) flobColors.addElement(color);
}
}
flobText = c.getText();
MediaZOb mz = getFromCache(c);
Image img = ScalableFont.fmComp.createImage(mz.getPixels().getSource());
ZZDrawingJ2D drw = null;
if (ZZDrawing.instance instanceof ZZDrawingJ2D)
drw = (ZZDrawingJ2D) ZZDrawing.instance;
if (drw != null) {
drw.setFIXME(false);
drw.setQuality(g);
}
if (mw == 0 && mh == 0)
g.drawImage(img, mx, my, mw, mh, imgobs);
else
g.drawImage(img, mx, my, mw, mh, null);
if (drw != null) {
drw.setFIXME(true);
drw.setQuality(g);
}
}
public Object hit(int hx,int hy) {
if (hx >= this.x && hy >= this.y && hx < this.x+this.w
&& hy < this.y+this.h) return handleCell;
return null;
}
};
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.height/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;
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);
}
}
// Local variables:
// tab-width: 4
// End:

View File

@@ -0,0 +1,40 @@
/*
MediaFlobView.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 Tero Mäyränen
*/
package org.gzigzag.module.multimedia;
import org.gzigzag.module.*;
import org.gzigzag.*;
import java.awt.*;
public class MediaFlobView extends Default implements FlobView
{
public static final String rcsid = "$Id: MediaFlobView.java,v 1.1 2001/03/05 08:44:14 deetsay Exp $";
private MediaFlobFactory mff = new MediaFlobFactory();
public void raster(FlobSet into, FlobFactory fact, ZZCell view, java.lang.String[] dims,
ZZCell accursed)
{
mff.placeFlob(into, accursed, accursed, 1, 0, 0, 1, 0, 0);
}
}

View File

@@ -0,0 +1,460 @@
/*
MediaMath.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 Tero Mäyränen
*/
package org.gzigzag.module.multimedia;
import org.gzigzag.*;
import java.awt.*;
import java.awt.image.*;
import java.util.*;
/**
* MediaMath is a collection of MediaZObs that do mathematical functions.
* If at all possible, in the future this should be done with some actual
* mathematical language designed for GZigZag...
*/
public class MediaMath
{
public static final String rcsid = "$Id: MediaMath.java,v 1.1 2001/03/05 08:44:14 deetsay Exp $";
public abstract class MathZOb extends MediaZOb
{
protected Pixels pix = null;
protected Vector oldframes = new Vector();
/**
* The inputs for these are just lists of MediaZObs connected on d.2,
* unlike the normal way, which is a list of parameter names, which
* in turn are connected to ZObs on d.1........
*/
protected Vector readInputPixels()
{
Vector v = new Vector();
Pixels inpix;
ZZCell d = cell;
do
{
inpix = MediaZOb.newMediaZOb(d).getPixels();
v.addElement(inpix);
d = d.s("d.2");
}
while ((d != null) && (!d.equals(cell)));
return v;
}
protected Vector readInputZObs()
{
Vector v = new Vector();
MediaZOb mz;
ZZCell d = cell;
do
{
mz = MediaZOb.newMediaZOb(d);
v.addElement(mz);
d = d.s("d.2");
}
while ((d != null) && (!d.equals(cell)));
return v;
}
/**
* Allocate enough pixels to fit all inputs in their correct coordinate positions.
*/
protected void createPix(Vector inputs)
{
if (inputs.size() < 1)
{
pix = new Pixels(1, 1);
pix.getPixels()[0] = 0xff000000;
return;
}
Pixels inpix = (Pixels)inputs.elementAt(0);
int w = inpix.getWidth(), h = inpix.getHeight();
int x = inpix.getX(), y = inpix.getY();
for (int i=1; i<inputs.size(); i++)
{
inpix = (Pixels)inputs.elementAt(i);
if (inpix.getX() < x)
{
w += x-inpix.getX();
x = inpix.getX();
}
if (inpix.getY() < y)
{
h += y-inpix.getY();
y = inpix.getY();
}
if ((inpix.getWidth() + inpix.getX()) > (w + x))
{
w = inpix.getWidth() + inpix.getX() - x;
}
if ((inpix.getHeight() + inpix.getY()) > (h + y))
{
h = inpix.getHeight() + inpix.getY() - y;
}
}
if (pix == null)
{
pix = new Pixels(w, h);
}
else
{
pix.setSize(w, h);
}
pix.setX(x);
pix.setY(y);
}
}
public class add extends MathZOb
{
public int getInt(int def)
{
Vector inputs = readInputZObs();
if (inputs.size() < 1) return def;
int S = 0;
for (int i=0; i<inputs.size(); i++) S += ((MediaZOb)inputs.elementAt(i)).getInt(0);
return S;
}
public Pixels getPixels()
{
Vector inputs = readInputPixels();
Pixels inpix;
/* if (pix != null && inputs.size() == oldframes.size())
{
boolean dirty = false;
for (int i=0; (i<inputs.size()) && (dirty==false); i++)
{
inpix = (Pixels)inputs.elementAt(i);
if (inpix.getFrame() != ((Integer)oldframes.elementAt(i)).intValue())
dirty = true;
}
if (!dirty) return pix;
}
oldframes.removeAllElements();
for (int i=0; i<inputs.size(); i++)
{
oldframes.addElement(new Integer(((Pixels)inputs.elementAt(i)).getFrame()));
}
*/
createPix(inputs);
int p[] = pix.getPixels(), ip[];
for (int i=0; i<(pix.getWidth()*pix.getHeight()); i++) p[i] = 0xff000000;
int pi, ipi;
int pp, ipp;
int r, g, b;
for (int i=0; i<inputs.size(); i++)
{
inpix = (Pixels)inputs.elementAt(i);
ip = inpix.getPixels();
ipi = 0;
pi = ((inpix.getY() - pix.getY()) * pix.getWidth()) + inpix.getX() - pix.getX();
for (int y=0; y<inpix.getHeight(); y++)
{
for (int x=0; x<inpix.getWidth(); x++)
{
ipp = ip[ipi++];
pp = p[pi];
r = (pp & 0xff0000) + (ipp & 0xff0000);
if (r > 0xff0000) r = 0xff0000;
g = (pp & 0xff00) + (ipp & 0xff00);
if (g > 0xff00) g = 0xff00;
b = (pp & 0xff) + (ipp & 0xff);
if (b > 0xff) b = 0xff;
p[pi++] = 0xff000000 | r | g | b;
}
pi += pix.getWidth() - inpix.getWidth();
}
}
pix.setFrame(pix.getFrame()+1);
return pix;
}
}
public class and extends MathZOb
{
public int getInt(int def)
{
Vector inputs = readInputZObs();
if (inputs.size() < 1) return def;
int S = 0xffffffff;
for (int i=0; i<inputs.size(); i++) S &= ((MediaZOb)inputs.elementAt(i)).getInt(0xffffffff);
return S;
}
public Pixels getPixels()
{
Vector inputs = readInputPixels();
Pixels inpix;
/* if (pix != null && inputs.size() == oldframes.size())
{
boolean dirty = false;
for (int i=0; (i<inputs.size()) && (dirty==false); i++)
{
inpix = (Pixels)inputs.elementAt(i);
if (inpix.getFrame() != ((Integer)oldframes.elementAt(i)).intValue())
dirty = true;
}
if (!dirty) return pix;
}
oldframes.removeAllElements();
for (int i=0; i<inputs.size(); i++)
{
oldframes.addElement(new Integer(((Pixels)inputs.elementAt(i)).getFrame()));
}
*/
createPix(inputs);
int p[] = pix.getPixels(), ip[];
for (int i=0; i<(pix.getWidth()*pix.getHeight()); i++) p[i] = 0xffffffff;
int pi, ipi;
int pp, ipp;
int r, g, b;
for (int i=0; i<inputs.size(); i++)
{
inpix = (Pixels)inputs.elementAt(i);
ip = inpix.getPixels();
ipi = 0;
pi = ((inpix.getY() - pix.getY()) * pix.getWidth()) + inpix.getX() - pix.getX();
for (int y=0; y<inpix.getHeight(); y++)
{
for (int x=0; x<inpix.getWidth(); x++)
{
ipp = ip[ipi++];
pp = p[pi];
p[pi++] = 0xff000000 | (pp & ipp);
}
pi += pix.getWidth() - inpix.getWidth();
}
}
pix.setFrame(pix.getFrame()+1);
return pix;
}
}
public class mul extends MathZOb
{
public int getInt(int def)
{
Vector inputs = readInputZObs();
if (inputs.size() < 1) return def;
int S = 1;
for (int i=0; i<inputs.size(); i++) S *= ((MediaZOb)inputs.elementAt(i)).getInt(1);
return S;
}
public Pixels getPixels()
{
Vector inputs = readInputPixels();
Pixels inpix;
/* if (pix != null && inputs.size() == oldframes.size())
{
boolean dirty = false;
for (int i=0; (i<inputs.size()) && (dirty==false); i++)
{
inpix = (Pixels)inputs.elementAt(i);
if (inpix.getFrame() != ((Integer)oldframes.elementAt(i)).intValue())
dirty = true;
}
if (!dirty) return pix;
}
oldframes.removeAllElements();
for (int i=0; i<inputs.size(); i++)
{
oldframes.addElement(new Integer(((Pixels)inputs.elementAt(i)).getFrame()));
}
*/
createPix(inputs);
int p[] = pix.getPixels(), ip[];
for (int i=0; i<(pix.getWidth()*pix.getHeight()); i++) p[i] = 0xffffffff;
int pi, ipi;
int pp, ipp;
int r, g, b;
for (int i=0; i<inputs.size(); i++)
{
inpix = (Pixels)inputs.elementAt(i);
ip = inpix.getPixels();
ipi = 0;
pi = ((inpix.getY() - pix.getY()) * pix.getWidth()) + inpix.getX() - pix.getX();
for (int y=0; y<inpix.getHeight(); y++)
{
for (int x=0; x<inpix.getWidth(); x++)
{
ipp = ip[ipi++];
pp = p[pi];
r = (((pp >> 12) & 0xff0) * ((ipp >> 12) & 0xff0)) & 0xff0000;
g = (((pp >> 8) & 0xff) * ((ipp >> 8) & 0xff)) & 0xff00;
b = ((pp & 0xff) * (ipp & 0xff)) >> 8;
p[pi++] = 0xff000000 | r | g | b;
}
pi += pix.getWidth() - inpix.getWidth();
}
}
pix.setFrame(pix.getFrame()+1);
return pix;
}
}
public class or extends MathZOb
{
public int getInt(int def)
{
Vector inputs = readInputZObs();
if (inputs.size() < 1) return def;
int S = 0;
for (int i=0; i<inputs.size(); i++) S |= ((MediaZOb)inputs.elementAt(i)).getInt(0);
return S;
}
public Pixels getPixels()
{
Vector inputs = readInputPixels();
Pixels inpix;
/* if (pix != null && inputs.size() == oldframes.size())
{
boolean dirty = false;
for (int i=0; (i<inputs.size()) && (dirty==false); i++)
{
inpix = (Pixels)inputs.elementAt(i);
if (inpix.getFrame() != ((Integer)oldframes.elementAt(i)).intValue())
dirty = true;
}
if (!dirty) return pix;
}
oldframes.removeAllElements();
for (int i=0; i<inputs.size(); i++)
{
oldframes.addElement(new Integer(((Pixels)inputs.elementAt(i)).getFrame()));
}
*/
createPix(inputs);
int p[] = pix.getPixels(), ip[];
for (int i=0; i<(pix.getWidth()*pix.getHeight()); i++) p[i] = 0xff000000;
int pi, ipi;
int pp, ipp;
int r, g, b;
for (int i=0; i<inputs.size(); i++)
{
inpix = (Pixels)inputs.elementAt(i);
ip = inpix.getPixels();
ipi = 0;
pi = ((inpix.getY() - pix.getY()) * pix.getWidth()) + inpix.getX() - pix.getX();
for (int y=0; y<inpix.getHeight(); y++)
{
for (int x=0; x<inpix.getWidth(); x++)
{
ipp = ip[ipi++];
pp = p[pi];
p[pi++] = 0xff000000 | pp | ipp;
}
pi += pix.getWidth() - inpix.getWidth();
}
}
pix.setFrame(pix.getFrame()+1);
return pix;
}
}
public class xor extends MathZOb
{
public int getInt(int def)
{
Vector inputs = readInputZObs();
if (inputs.size() < 1) return def;
int S = 0;
for (int i=0; i<inputs.size(); i++) S ^= ((MediaZOb)inputs.elementAt(i)).getInt(0);
return S;
}
public Pixels getPixels()
{
Vector inputs = readInputPixels();
Pixels inpix;
/* if (pix != null && inputs.size() == oldframes.size())
{
boolean dirty = false;
for (int i=0; (i<inputs.size()) && (dirty==false); i++)
{
inpix = (Pixels)inputs.elementAt(i);
if (inpix.getFrame() != ((Integer)oldframes.elementAt(i)).intValue())
dirty = true;
}
if (!dirty) return pix;
}
oldframes.removeAllElements();
for (int i=0; i<inputs.size(); i++)
{
oldframes.addElement(new Integer(((Pixels)inputs.elementAt(i)).getFrame()));
}
*/
createPix(inputs);
int p[] = pix.getPixels(), ip[];
for (int i=0; i<(pix.getWidth()*pix.getHeight()); i++) p[i] = 0xff000000;
int pi, ipi;
int pp, ipp;
int r, g, b;
for (int i=0; i<inputs.size(); i++)
{
inpix = (Pixels)inputs.elementAt(i);
ip = inpix.getPixels();
ipi = 0;
pi = ((inpix.getY() - pix.getY()) * pix.getWidth()) + inpix.getX() - pix.getX();
for (int y=0; y<inpix.getHeight(); y++)
{
for (int x=0; x<inpix.getWidth(); x++)
{
ipp = ip[ipi++];
pp = p[pi];
p[pi++] = 0xff000000 | pp ^ ipp;
}
pi += pix.getWidth() - inpix.getWidth();
}
}
pix.setFrame(pix.getFrame()+1);
return pix;
}
}
}

View File

@@ -0,0 +1,216 @@
/*
MediaZOb.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 Tero Mäyränen
*/
package org.gzigzag.module.multimedia;
import org.gzigzag.module.*;
import org.gzigzag.*;
import java.awt.*;
/**
*/
public abstract class MediaZOb implements ZOb
{
public static final String rcsid = "$Id: MediaZOb.java,v 1.7 2001/03/05 08:44:14 deetsay 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); }
protected ZZCell cell = null;
protected ZZCell callFrom = null;
public void setMacro(ZZCell cf) { callFrom = cf; }
static private MediaZOb nullZOb = new Default();
static private MediaMath mediaMath = new MediaMath();
/**
* This is the readParams method, defined in the ZOb interface.
* Unlike in most ZObs, this method doesn't read parameters from
* the structure: it only sets the cell for reading the parameters later.
*/
public String readParams(ZZCell c) { cell = c; return ""; }
static public MediaZOb newMediaZObNoDefault(ZZCell c)
{
if (c == null) return nullZOb;
c = c.h("d.clone");
ZZCell cc;
MediaZOb mz;
/*
* psssssst!.... this is a secret feature:
* you can show images from the old-fashioned
* file:// or http:// protocols... :-)
*/
try
{
if (c.getText().indexOf("://") >= 0)
{
mz = new image();
mz.readParams(c);
return mz;
}
}
catch (Exception e) {}
cc = c.s("d.1");
if (cc == null) return null;
ZZCell macroCell = cc;
cc = macroCell.h("d.clone");
if (macroCell.equals(cc)) macroCell = null;
String t = cc.getText();
int x;
/*
* This is an unnecessary check just because
* you get some errors if you try newZOb() on an URL :-)
*/
if (t.indexOf("://") >= 0) return null;
x = t.indexOf('.');
if (x > 1) try
{
mz = (MediaZOb)ZZModule.getModule(t.substring(0, x)).newZOb(t.substring(x + 1));
mz.readParams(cc.s("d.1"));
if (macroCell != null) mz.setMacro(macroCell);
return mz;
}
catch (Exception e) {}
/*
* Mathematical functions are hidden inside MediaMath..
*/
if (t.equals("+")) { mz = mediaMath.new add(); mz.readParams(cc.s("d.1")); return mz; }
if (t.equals("&")) { mz = mediaMath.new and(); mz.readParams(cc.s("d.1")); return mz; }
if (t.equals("*")) { mz = mediaMath.new mul(); mz.readParams(cc.s("d.1")); return mz; }
if (t.equals("|")) { mz = mediaMath.new or(); mz.readParams(cc.s("d.1")); return mz; }
if (t.equals("%")) { mz = mediaMath.new xor(); mz.readParams(cc.s("d.1")); return mz; }
return null;
}
static public MediaZOb newMediaZOb(ZZCell c)
{
MediaZOb mz = newMediaZObNoDefault(c);
if (mz == null)
{
mz = new Default();
mz.readParams(c);
}
return mz;
}
/**
* Find a parameter of this cell from the ZZ-structure, and
* return it as a MediaZOb.
*
* @param name is the name of the parameter that you hope to find.
*/
protected MediaZOb readParam(String name)
{
MediaZOb mz = null;
if (cell == null) return nullZOb;
mz = readParam(name, cell, null);
return (mz == null ? nullZOb : mz);
}
/**
* Recursive part of the previous method
*/
private MediaZOb readParam(String name, ZZCell key, ZZCell first)
{
if ((key == null) || key.equals(first)) return null;
if (first == null) first = key;
if ((name != null) && (name.equals(key.getText())))
{
ZZCell value = key.s("d.1");
//-------------------------------------------------
// An acceptable way of passing macro parameters?
if ((value != null) && (value.getText().equals("param")))
{
MediaZOb mz = null;
ZZCell parname = value.s("d.1");
if (parname != null)
{
if (callFrom != null)
mz = readParam(parname.getText(), callFrom.s("d.1"), null);
if (mz == null)
mz = newMediaZOb(parname.s("d.1"));
return mz;
}
}
//-------------------------------------------------
return newMediaZOb(value);
}
return readParam(name, key.s("d.2"), first);
}
/**
* Contents of cell as text.
*
* @param def Default value.
*/
public String getText(String def)
{
return (cell == null ? def : cell.getText());
}
/**
* Contents of cell as integer.
*
* @param def Default value.
*/
public int getInt(int def)
{
String t = getText("");
// try to parse hex
try { if (t.substring(0, 2).equals("0x")) return Integer.parseInt(t.substring(2), 16); }
catch (Exception e) {}
// try to parse decimal
try { return Integer.parseInt(t); } catch (Exception e) {}
return def;
}
public abstract Pixels getPixels();
}
// Local variables:
// tab-width: 4
// End:

View File

@@ -0,0 +1,163 @@
/*
Pixels.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 Tero Mäyränen
*/
package org.gzigzag.module.multimedia;
import java.awt.*;
import java.awt.image.*;
import java.util.*;
/**
* The purpose of this class is to be the type of return value
* for MediaZOb's getPixels() method.
*
* @see MediaZOb
*/
public class Pixels
{
public static final String rcsid = "$Id: Pixels.java,v 1.2 2001/03/05 08:44:14 deetsay Exp $";
private int width, height, x, y;
private int allocatedSize;
private int pixels[];
private int frame = 0;
public int getFrame() { return frame; }
public void setFrame(int f) { frame = f; }
public int getX() { return x; }
public int getY() { return y; }
public int getCenterX() { return x + (width >> 1); }
public int getCenterY() { return y + (height >> 1); }
public void setX(int a) { x = a; }
public void setY(int a) { y = a; }
public void setCenterX(int a) { x = a - (width >> 1); }
public void setCenterY(int a) { y = a - (height >> 1); }
public int getWidth() { return width; }
public int getHeight() { return height; }
private void checkSize()
{
int newsize = width*height;
if (newsize > allocatedSize)
{
pixels = null;
allocatedSize = newsize;
pixels = new int[allocatedSize];
}
}
public void setSize(int a, int b)
{
width = a;
height = b;
checkSize();
}
public void setWidth(int a)
{
width = a;
checkSize();
}
public void setHeight(int a)
{
height = a;
checkSize();
}
public void setCenterWidth(int a)
{
x += ((width - a) >> 1);
width = a;
checkSize();
}
public void setCenterHeight(int a)
{
y += ((height - a) >> 1);
height = a;
checkSize();
}
public int[] getPixels() { return pixels; }
/**
* Thanks to this method there's no need to use MemoryImageSource
* to get an Image from pixel data.
*/
public ImageProducer getSource()
{
return new ImageProducer()
{
private Vector imageConsumers = new Vector();
public void addConsumer(ImageConsumer ic)
{
if ((ic != null) && (!isConsumer(ic)))
{
imageConsumers.addElement(ic);
}
}
public boolean isConsumer(ImageConsumer ic)
{
return imageConsumers.contains(ic);
}
public void removeConsumer(ImageConsumer ic)
{
imageConsumers.removeElement(ic);
}
public void requestTopDownLeftRightResend(ImageConsumer ic)
{
startProduction(ic);
}
public void startProduction(ImageConsumer ic)
{
addConsumer(ic);
int i = 0;
ImageConsumer cons;
try
{
while (true)
{
cons = (ImageConsumer)imageConsumers.elementAt(i++);
cons.setDimensions(getWidth(), getHeight());
cons.setHints(ImageConsumer.TOPDOWNLEFTRIGHT
| ImageConsumer.SINGLEFRAME | ImageConsumer.SINGLEPASS);
cons.setPixels(0, 0, getWidth(), getHeight(), ColorModel.getRGBdefault(),
getPixels(), 0, getWidth());
cons.imageComplete(ImageConsumer.STATICIMAGEDONE);
}
}
catch (Exception e) {}
}
};
}
public Pixels(int w, int h)
{
x = 0;
y = 0;
width = w;
height = h;
pixels = new int[width*height];
}
}

View File

@@ -0,0 +1,61 @@
/*
PolygonRenderer.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 Tero Mäyränen
*/
package org.gzigzag.module.multimedia;
import org.gzigzag.*;
import java.awt.*;
import java.awt.image.*;
import java.util.*;
/**
* unfinished..
*/
public class PolygonRenderer extends MediaZOb
{
public static final String rcsid = "$Id: PolygonRenderer.java,v 1.1 2001/03/05 08:44:14 deetsay Exp $";
private Pixels pix;
public Pixels getPixels()
{
int w = readParam("width").getInt(256);
int h = readParam("height").getInt(256);
if (pix == null)
{
pix = new Pixels(w, h);
}
else
{
pix.setSize(w, h);
}
int p[] = pix.getPixels();
for (int i=0; i<(w*h); i++) p[i] = 0xff000000;
/* sort polygons */
/* render */
return pix;
}
}

View File

@@ -0,0 +1,65 @@
/*
Polygons.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 Tero Mäyränen
*/
package org.gzigzag.module.multimedia;
import org.gzigzag.*;
import java.awt.*;
import java.awt.image.*;
import java.util.*;
/**
* unfinished
*/
public class Polygons
{
public static final String rcsid = "$Id: Polygons.java,v 1.1 2001/03/05 08:44:14 deetsay Exp $";
public class PolyPoint
{
public int x, y, z;
public int tx, ty, ex, ey, bx, by;
}
public class Polygon
{
public PolyPoint points[];
public Polygon()
{
points = new PolyPoint[3];
}
}
private PolyPoint points[];
private Polygon polygons[];
public PolyPoint[] getPoints() { return points; }
public Polygon[] getPolygons() { return polygons; }
public Polygons(int npoints, int npolygons)
{
points = new PolyPoint[npoints];
polygons = new Polygon[npolygons];
}
}

View File

@@ -0,0 +1,109 @@
/*
adjust.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 Tero Mäyränen
*/
package org.gzigzag.module.multimedia;
import org.gzigzag.*;
import java.awt.*;
import java.awt.image.*;
import java.util.*;
/**
* unfinished
*/
public class adjust extends MediaZOb
{
public static final String rcsid = "$Id: adjust.java,v 1.1 2001/03/05 08:44:14 deetsay Exp $";
private Pixels pix = null;
private int oldframe=0, oldradj=0, oldgadj=0, oldbadj=0, oldhadj=0, oldsadj=0, oldbradj=0;
public Pixels getPixels()
{
Pixels inpix = readParam("input").getPixels();
int radj = readParam("red").getInt(100);
int gadj = readParam("green").getInt(100);
int badj = readParam("blue").getInt(100);
int hadj = readParam("hue").getInt(100);
int sadj = readParam("saturation").getInt(100);
int bradj = readParam("brightness").getInt(100);
if (pix != null && inpix.getFrame() == oldframe
&& radj == oldradj && gadj == oldgadj && badj == oldbadj
&& hadj == oldhadj && sadj == oldsadj && bradj == oldbradj)
{
return pix;
}
oldradj = radj; oldgadj = gadj; oldbadj = badj;
oldhadj = hadj; oldsadj = sadj; oldbradj = bradj;
oldframe = inpix.getFrame();
int w = inpix.getWidth();
int h = inpix.getHeight();
int px = inpix.getX();
int py = inpix.getY();
if (pix == null)
{
pix = new Pixels(w, h);
}
else
{
pix.setSize(w, h);
}
pix.setX(px);
pix.setY(py);
float hsbvals[] = new float[3];
int ip[] = inpix.getPixels();
int pred, pgreen, pblue, prgb;
int op[] = pix.getPixels();
for (int i=0; i<(w*h); i++)
{
prgb = ip[i];
pred = ((prgb >> 16) & 0xff) * radj / 100;
pgreen = ((prgb >> 8) & 0xff) * gadj / 100;
pblue = (prgb & 0xff) * badj / 100;
Color.RGBtoHSB(
(pred > 255 ? 255 : pred),
(pgreen > 255 ? 255 : pgreen),
(pblue > 255 ? 255 : pblue),
hsbvals);
hsbvals[0] = hsbvals[0] * hadj / 100;
hsbvals[1] = hsbvals[1] * sadj / 100;
hsbvals[2] = hsbvals[2] * bradj / 100;
op[i] = Color.HSBtoRGB(
(hsbvals[0] > 1 ? 1 : hsbvals[0]),
(hsbvals[1] > 1 ? 1 : hsbvals[1]),
(hsbvals[2] > 1 ? 1 : hsbvals[2]));
}
return pix;
}
}

View File

@@ -0,0 +1,94 @@
/*
crop.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 Tero Mäyränen
*/
package org.gzigzag.module.multimedia;
import org.gzigzag.*;
import java.awt.*;
import java.awt.image.*;
import java.util.*;
/**
* unfinished
*/
public class crop extends MediaZOb
{
public static final String rcsid = "$Id: crop.java,v 1.2 2001/03/05 08:44:14 deetsay Exp $";
private Pixels pix = null;
private int oldframe=0, oldpw=0, oldph=0, oldpx=0, oldpy=0;
public Pixels getPixels()
{
Pixels inpix = readParam("input").getPixels();
int iw = inpix.getWidth();
int ih = inpix.getHeight();
int ix = inpix.getX();
int iy = inpix.getY();
int pw = readParam("width").getInt(iw);
int ph = readParam("height").getInt(ih);
int px = readParam("x").getInt(ix);
int py = readParam("y").getInt(iy);
if (pix != null && inpix.getFrame() == oldframe
&& pw == oldpw && ph == oldph && px == oldpx && py == oldpy)
{
return pix;
}
oldpw = pw; oldph = ph; oldpx = px; oldpy = py; oldframe = inpix.getFrame();
if (pix == null)
{
pix = new Pixels(pw, ph);
}
else
{
pix.setSize(pw, ph);
}
pix.setX(px);
pix.setY(py);
int p[] = pix.getPixels(), ip[] = inpix.getPixels();
int i = 0;
for (int y=py; y<py+ph; y++)
{
if ((y < iy) || (y >= iy + ih))
{
for (int x=0; x<pw; x++) p[i++] = 0xff000000;
}
else
{
for (int x=px; x<px+pw; x++)
{
if ((x < ix) || (x >= ix + iw)) p[i++] = 0xff000000;
else p[i++] = ip[ ((y-iy)*iw)+(x-ix) ];
}
}
}
pix.setFrame(pix.getFrame()+1);
return pix;
}
}

View File

@@ -0,0 +1,58 @@
/*
dots.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 Tero Mäyränen
*/
package org.gzigzag.module.multimedia;
import org.gzigzag.*;
import java.awt.*;
import java.awt.image.*;
import java.util.*;
public class dots extends MediaZOb
{
public static final String rcsid = "$Id: dots.java,v 1.2 2001/03/05 08:44:14 deetsay Exp $";
private Pixels pix = null;
private void plot(int p[], int w, int h, int n)
{
}
public Pixels getPixels()
{
if (pix == null)
{
int w = readParam("width").getInt(64);
int h = readParam("height").getInt(64);
int c = readParam("bg").getInt(0);
pix = new Pixels(w, h);
int p[] = pix.getPixels();
for (int i=0; i<(w*h); i++)
{
p[i] = 0xff000000 | c;
}
plot(p, w, h, readParam("dots").getInt(100));
}
return pix;
}
}

View File

@@ -0,0 +1,102 @@
/*
image.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 Tero Mäyränen
*/
package org.gzigzag.module.multimedia;
import org.gzigzag.*;
import java.awt.*;
import java.awt.image.*;
import java.util.*;
import java.net.*;
/** Image mediazob.
* Images can be read from a different place by setting the property images.from,
* like
* java -Dimages.from=img:///=file:///home/antkaij/cvs/gzigzag-demo/Java/demospace-lomat.2.zz/ org.gzigzag.Main demospace-lomat.2.zz
*/
public class image extends MediaZOb
{
public static final String rcsid = "$Id: image.java,v 1.7 2001/02/28 05:16:55 tjl 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); }
private static Hashtable convert = null;
private Pixels pix = null;
private static String doConvert(String str) {
if (convert == null) {
convert = new Hashtable();
String prop = null;
try {
prop = System.getProperty("images.from");
} catch(Throwable t) {}
if (prop != null) {
StringTokenizer tok = new StringTokenizer(prop, ";=");
while (tok.hasMoreTokens()) {
String a = tok.nextToken();
String b = tok.nextToken();
p(""+a+" => "+b);
convert.put(a, b);
}
}
}
for(Enumeration e = convert.keys(); e.hasMoreElements(); ) {
String from = (String)e.nextElement();
p(""+str+"; "+from);
if (!str.startsWith(from)) continue;
String to = (String)convert.get(from);
p(""+str+" => "+to + str.substring(from.length()));
str = to + str.substring(from.length());
return str;
}
p("Not converted: "+str);
return str;
}
public Pixels getPixels()
{
if (pix == null)
{
try
{
URL imgURL = new URL(doConvert(getText("")));
p("URL: "+imgURL);
Image img = Toolkit.getDefaultToolkit().getImage(imgURL);
int w = img.getWidth(null);
int count = 2000000;
while ((w < 0) && (count-- > 0)) w = img.getWidth(null);
int h = img.getHeight(null);
pix = new Pixels(w, h);
PixelGrabber pg = new PixelGrabber(img, 0, 0, w, h, pix.getPixels(), 0, w);
pg.grabPixels();
}
catch (Exception e) {}
}
return pix;
}
}
// Local variables:
// tab-width: 4
// End:

View File

@@ -0,0 +1,51 @@
/*
mm.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 Tero Mäyränen
*/
package org.gzigzag.module;
import org.gzigzag.module.multimedia.*;
import org.gzigzag.*;
import java.awt.*;
/**
* Module for multimedia stuff.
*/
public class mm
{
static public final String rcsid = "$Id: mm.java,v 1.3 2001/03/05 08:44:14 deetsay Exp $";
static public ZZModule module = new ZZModule()
{
public ZOb newZOb(String id)
{
try
{
return (ZOb)Class.forName("org.gzigzag.module.multimedia." + id).newInstance();
}
catch (Exception e)
{
// ZZLogger.exc(e);
return null;
}
}
};
}

View File

@@ -0,0 +1,70 @@
/*
move.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 Tero Mäyränen
*/
package org.gzigzag.module.multimedia;
import org.gzigzag.*;
import java.awt.*;
import java.awt.image.*;
import java.util.*;
public class move extends MediaZOb
{
public static final String rcsid = "$Id: move.java,v 1.2 2001/03/05 08:44:14 deetsay Exp $";
Pixels pix = null;
private int oldframe=0, oldx=0, oldy=0;
public Pixels getPixels()
{
Pixels inpix = readParam("input").getPixels();
int x = readParam("x").getInt(0);
int y = readParam("y").getInt(0);
if (pix != null && inpix.getFrame() == oldframe && x == oldx && y == oldy)
{
return pix;
}
oldframe = inpix.getFrame(); oldx = x; oldy = y;
int w = inpix.getWidth();
int h = inpix.getHeight();
if (pix == null)
{
pix = new Pixels(w, h);
}
else
{
pix.setSize(w, h);
}
pix.setX(inpix.getX() + x);
pix.setY(inpix.getY() + y);
int p[] = pix.getPixels(), ip[] = inpix.getPixels();
for (int i=0; i<w*h; i++) p[i] = ip[i];
pix.setFrame(pix.getFrame()+1);
return pix;
}
}

View File

@@ -0,0 +1,107 @@
<html>
<head>
<title>Multimedia module</title>
<!-- // $Id: readme.html,v 1.2 2001/03/05 08:44:14 deetsay Exp $ // -->
<script language="javascript">
<!--
function nop(c)
{
return '<td colspan="'+c+'"></td>\n';
}
function cell(p)
{
return '<td>'
+ '<table cellspacing=0 cellpadding=2 border=0><tr><td bgcolor="#000000">'
+ '<table cellspacing=0 cellpadding=4 border=0><tr><td bgcolor="#ffff00">'
+ p + '</td></tr></table></td></tr></table></td>\n';
}
function hconn(p)
{
var t = '';
var i;
for (i=0; i<8; i++) { t = t + '&nbsp;'; }
return '<td><font size="-1"><u>'+t+p+t+'</u></font></td>\n';
}
function vconn(p)
{
return '<td>| <font size="-1">'+p+'</font></td>\n';
}
function figure(p, t)
{
return '<center>'
+ '<table cellspacing=0 cellpadding=16 border=0><tr><td bgcolor="#ffcc00">\n'
+ '<table cellspacing=0 cellpadding=0 border=0><tr>\n'
+ p + '</tr></table></td></tr></table>\n'
+ '<b>Fig. ' + t + '</b><br>\n</center>\n';
}
// -->
</script>
</head>
<body bgcolor="#ffffff" text="#000000">
<h2>1. How to use MediaZObs</h2>
<script language="javascript">
<!-- //
document.write(figure(
cell('<i>The picture created by the MediaZOb would be shown in this cell. '
+'The text contents of this cell are inconsequential, for example it could be a name '
+'for this picture.</i>')
+hconn('d.1')+cell('<i>name of MediaZOb</i>')+hconn('d.1')+cell('&nbsp;')+nop(2)
+'</tr><tr>'
+nop(4)+vconn("d.2")+nop(2)
+'</tr><tr>'
+nop(4)+cell('parameter')+hconn('d.1')+cell('value')
+'</tr><tr>'
+nop(4)+vconn("d.2")+nop(2)
+'</tr><tr>'
+nop(4)+cell('parameter')+hconn('d.1')+cell('value')
+'</tr><tr>'
+nop(4)+vconn("d.2")+nop(2),
'1.1. The structure of a typical MediaZOb.'
));
// -->
</script>
<h2>2. How to use macros</h2>
To define a macro:
<ul>
<li>Just use the MediaZOb you want to use ("mm.rect" below).</li><br>
<li>Replace some of the parameters with the word "param" :-)</li><br>
<li>To the cell next from "param" on "d.1" write the name of your
parameter. ("mywidth" below)</li><br>
<li>Optional: To the cell next on "d.1" write a default value.</li><br>
</ul>
<script language="javascript">
<!-- //
document.write(figure(
nop(2)+cell('mm.rect')+hconn('d.1')+cell('&nbsp;')+nop(6)+'</tr><tr>'
+nop(2)+vconn('')+nop(1)+vconn('d.2')+nop(6)+'</tr><tr>'
+nop(2)+vconn('d.clone')+nop(1)+cell('width')+hconn('d.1')+cell('param')+hconn('d.1')+cell('mywidth')+hconn('d.1')+cell('50')+'</tr><tr>'
+nop(2)+vconn('')+nop(8)+'</tr><tr>'
+cell('<i>a rectangle will show up here</i>')
+hconn('d.1')+cell('mm.rect')+hconn('d.1')+cell('&nbsp;')+nop(6)+'</tr><tr>'
+nop(4)+vconn('d.2')+nop(6)+'</tr><tr>'
+nop(4)+cell('mywidth')+hconn('d.1')+cell('100')+nop(4),
'2.1. The structure of a macro.'
));
// -->
</script>
To use a macro:
<ul>
<li>Clone the name of the MediaZOb...</li><br>
<li>Give the clone some of the parameters you have used in your
macro definition.</li><br>
</ul>
</body>
</html>

View File

@@ -0,0 +1,122 @@
/*
rect.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 Tero Mäyränen
*/
package org.gzigzag.module.multimedia;
import org.gzigzag.*;
import java.awt.*;
import java.awt.image.*;
import java.util.*;
public class rect extends MediaZOb
{
public static final String rcsid = "$Id: rect.java,v 1.4 2001/03/05 08:44:14 deetsay Exp $";
private Pixels pix = null;
private int fade(int x, int fg, int bg)
{
int y = 0xff-x;
return 0xff000000
| (((((fg & 0xff0000) * x) + ((bg & 0xff0000) * y)) >> 8) & 0xff0000)
| (((((fg & 0xff00) * x) + ((bg & 0xff00) * y)) >> 8) & 0xff00)
| (((((fg & 0xff) * x) + ((bg & 0xff) * y)) >> 8) & 0xff);
}
private int oldw=0, oldh=0, oldbg=0, oldfg=0, oldstarsize=0;
private String oldmode="";
public Pixels getPixels()
{
int w = readParam("width").getInt(64);
int h = readParam("height").getInt(64);
int bg = readParam("bg").getInt(0);
int fg = readParam("fg").getInt(0xffffff);
int starsize = readParam("size").getInt(16);
if (starsize==0) starsize=1;
String mode = readParam("fillmode").getText("solid");
if (pix != null && oldw==w && oldh==h && oldbg==bg && oldfg==fg
&& oldstarsize==starsize && mode.equals(oldmode))
{
return pix;
}
oldw=w; oldh=h; oldbg=bg; oldfg=fg; oldstarsize=starsize; oldmode=mode;
if (pix == null)
{
pix = new Pixels(w, h);
}
else
{
pix.setSize(w, h);
}
int p[] = pix.getPixels();
if (mode.equals("solid"))
{
for (int i=0; i<(w*h); i++)
{
p[i] = 0xff000000 | fg;
}
}
if (mode.equals("starburst"))
{
// älä optiomoi, vaihda algoritmia
int w2 = w >> 1;
int h2 = h >> 1;
int i = 0, j;
for (int y=-h2; y<h-h2; y++)
{
for (int x=-w2; x<w-w2; x++)
{
j = ((int)Math.sqrt(x*x+y*y)*(256 / starsize));
if (j > 0xff) j = 0xff;
p[i++] = fade(j, bg, fg);
}
}
}
if (mode.equals("radial"))
{
int w2 = w >> 1;
int h2 = h >> 1;
int i = 0, j = w, i2 = w*h, j2 = (w*h)-w, k;
for (int y=-h2; y<0; y++)
{
for (int x=-w2; x<0; x++)
{
k = ((int)(Math.atan(((double)x) / y) * 128 / Math.PI)) & 0x3f;
p[i++] = fade(k, bg, fg);
p[--j] = fade(k, fg, bg);
p[--i2] = fade(k | 0x80, bg, fg);
p[j2++] = fade(k | 0x80, fg, bg);
}
i += w2;
j += w + w2;
i2 -= w2;
j2 -= w + w2;
}
}
pix.setFrame(pix.getFrame()+1);
return pix;
}
}

View File

@@ -0,0 +1,42 @@
/*
sin.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 Tero Mäyränen
*/
package org.gzigzag.module.multimedia;
import org.gzigzag.module.*;
import org.gzigzag.*;
import java.awt.*;
/**
*/
public class sin extends Default
{
public static final String rcsid = "$Id: sin.java,v 1.1 2001/03/05 08:44:14 deetsay Exp $";
public int getInt(int def)
{
int a = ((int)System.currentTimeMillis()) >> 7;
return ((int)(Math.sin(((double)a * readParam("speed").getInt(64)) / (Math.PI * 100))
* readParam("amplitude").getInt(16))) + readParam("bias").getInt(64);
}
}

327
Modules/nile/Nile1.java Normal file
View File

@@ -0,0 +1,327 @@
/*
Nile1.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.module;
import org.gzigzag.*;
import java.util.*;
import java.awt.*;
import java.io.*;
/** A stream with parallel markup.
* <p>
* Character-level formatting is currently done using B and I (as in HTML,
* for bold and italics). These are placed in cells whose headcell
* on <code>d.nile-fmt-start</code> is the cell in the stream that the
* markup starts from. Likewise, their headcell on <code>d.nile-fmt-end</code>
* is the last cell that does have this markup.
* This is a bit fragile with reordering but most effects can be limited by
* knowing that all formats are allowed to touch only things inside a paragraph
* and we can run a fixer script every once in a while.
* <p>
* Paragraph-, section- and chapter -level markup is done by cells
* that say the level: P, H1..H6 on the dimension
* <code>d.nile-struct</code>. These are interpreted by the space part
* so that the HOP operation can be used to move things around easily.
* For higher-than-paragraph level sectioning, the part starting at
* the section, up to the next paragraph or section is considered the
* heading.
* So, in <pre>H1 foo H2 bar P ab H2 zzz P cd</pre>,
* the headings would be foo, bar and zzz.
*/
public class Nile1 {
public static final String rcsid = "$Id: Nile1.java,v 1.10 2001/01/26 13:53: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); }
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) {
ZZUpdateManager.setFast(view);
ZZCell viewCell = view.getViewcell();
ZZCell otherCell = viewCell.s("d.nile-wins");
boolean split = false;
ZZCell viewAcc = ZZCursorReal.get(viewCell);
ZZCell leftCell = viewAcc.s("d.nile-pair", -1);
ZZCell rightCell = viewAcc.s("d.nile-pair");
if(leftCell != null || rightCell != null) {
split = true;
if(leftCell != null) {
rightCell = viewAcc;
viewCell = rightCell;
otherCell = leftCell;
} else {
leftCell = viewAcc;
viewCell = leftCell;
otherCell = rightCell;
}
}
p("Nile action: id: '"+id+"' key: '"+key+"' code: "+code);
StringTokenizer st = new StringTokenizer(id);
String[] toks = new String[st.countTokens()];
for(int i=0; i<toks.length; i++)
toks[i] = st.nextToken();
int dir = 0;
Nile2Unit unit = null;
if(toks.length > 1) {
if(toks[1].equals("+")) dir = 1;
else if(toks[1].equals("-")) dir = -1;
if(toks.length > 2) {
if(toks[2].equals("CHAR"))
unit = new Nile2Unit.Char();
else if(toks[2].equals("WORD"))
unit = new Nile2Unit.Word();
else if(toks[2].equals("SENT"))
unit = new Nile2Unit.Sentence();
else if(toks[2].equals("PARA"))
unit = new Nile2Unit.Paragraph();
}
}
id = toks[0];
if(id.equals("Cursor")) {
p("Cursor: "+dir);
Nile2Ops.moveCursor(unit, viewCell, dir);
ZZUpdateManager.setFast(null);
}
else if(id.equals("AdjLeft")) {
Nile2Ops.adjust(unit, viewCell, -1, dir);
ZZUpdateManager.setFast(null);
}
else if(id.equals("AdjRight")) {
Nile2Ops.adjust(unit, viewCell, 1, dir);
ZZUpdateManager.setFast(null);
}
else if(id.equals("Hop")) {
Nile2Ops.hop(unit, viewCell, dir);
}
else if(id.equals("Mode")) {
Nile2Ops.setCursor(unit, viewCell, null);
if(split)
Nile2Ops.setCursor(unit, otherCell, null);
}
else if(id.equals("Insert")) {
Nile2Ops.insert(viewCell, key);
// Set the selection of other half to char mode, too
if(split)
Nile2Ops.setCursor(new Nile2Unit.Char(), otherCell, null);
}
else if(id.equals("BackSpace")) {
Nile2Ops.backspace(unit, viewCell);
}
else if(id.equals("Delete")) {
Nile2Ops.del(unit, viewCell);
}
else if(id.equals("BreakParagraph")) {
Nile2Ops.breakParagraph(unit, viewCell);
}
else if(id.equals("Tunnel")) {
if(otherCell != null) {
Nile2Ops.tunnel(unit, otherCell, viewCell, dir, false);
}
}
else if(id.equals("Transcopy")) {
if(otherCell != null) {
Nile2Ops.tunnel(unit, otherCell, viewCell, dir, true);
}
}
else if(id.equals("PUICopy")) {
ZZCell c = ZZCursorReal.get(viewCell);
String s = Nile2Ops.stringify(c);
ZZUtil.puiCopy(s);
}
/*
else if(id.equals("TraverseTranscopies")) {
Nile2Ops.traverseTranscopies(viewCell, dir);
}
*/
Object ob = null;
if(pt != null)
ob = xi.getObjectAt(pt.x, pt.y);
if(id.equals("MouseSetCursor")) {
p("Setting cursor from mouse! Unit: "+unit);
if(split) {
// Brute force: was the click in left window half?
if(pt.x < ((FlobSet)xi).getSize().width/2) {
viewCell = leftCell; otherCell = rightCell;
} else {
viewCell = rightCell; otherCell = leftCell;
}
ZZCursorReal.set(view.getViewcell(), viewCell);
}
Nile2Ops.setCursor(unit, viewCell, (ZZCursor)ob);
}
}
public ZOb newZOb(String id) {
if(id.equals("Normal")) {
return new Nile1View();
} else if(id.equals("Parallel")) {
return new SplitNileView();
}
return null;
}
};
// This is really hacky part...
static ZZCell curAct;
static void a(String key, String act) { a(key, act, null); }
static void a(String key, String act, ZZCell next) {
curAct = curAct.N("d.2", 1);
curAct.setText(key);
ZZCell n = curAct.N("d.1", 1);
n.setText("Nile1." + act);
if(next != null)
next.insert("d.3", 1, n);
}
static void actions(ZZCell start) {
start.setText("Nile char");
ZZCell nchar = start;
ZZCell nword = nchar.N("d.1", 1); nword.setText("Nile word");
ZZCell nsent = nword.N("d.1", 1); nsent.setText("Nile sent");
ZZCell npara = nsent.N("d.1", 1); npara.setText("Nile para");
ZZCell ncommon = npara.N("d.1", 1); ncommon.setText("Nile common");
curAct = nword;
// Annoying - these should be structurally
// describable!!!
a("MouseClicked1", "MouseSetCursor 0 WORD");
a("Backspace", "BackSpace 0 WORD");
a("Delete", "Delete 0 WORD");
a("Alt-Backspace", "Delete 0 WORD");
a("Ctrl-P", "Tunnel - WORD"); // P for pull
a("Ctrl-T", "Transcopy - WORD");
a("Left", "Cursor - WORD");
a("Right", "Cursor + WORD");
a("Shift-Left", "AdjLeft - WORD");
a("Shift-Right", "AdjRight + WORD");
a("Ctrl-Left", "AdjRight - WORD");
a("Ctrl-Right", "AdjLeft + WORD");
a("Alt-Left", "Hop - WORD");
a("Alt-Right", "Hop + WORD");
a("Enter", "BreakParagraph 0 WORD");
a("Up", "Cursor - SENT");
a("Down", "Cursor + SENT");
a("Alt-Up", "Hop - SENT");
a("Alt-Down", "Hop + SENT");
a("INSERT", "Insert", nchar);
a("Tab", "Mode 0 SENT", nsent);
curAct = nsent;
a("MouseClicked1", "MouseSetCursor 0 SENT");
a("Backspace", "BackSpace 0 SENT");
a("Delete", "Delete 0 SENT");
a("Alt-Backspace", "Delete 0 SENT");
a("Ctrl-P", "Tunnel - SENT"); // P for push
a("Ctrl-T", "Transcopy - SENT");
a("Left", "Cursor - SENT");
a("Right", "Cursor + SENT");
a("Shift-Left", "AdjLeft - SENT");
a("Shift-Right", "AdjRight + SENT");
a("Ctrl-Left", "AdjRight - SENT");
a("Ctrl-Right", "AdjLeft + SENT");
a("Alt-Left", "Hop - SENT");
a("Alt-Right", "Hop + SENT");
a("Enter", "BreakParagraph 0 SENT");
a("Up", "Cursor - PARA");
a("Down", "Cursor + PARA");
a("Alt-Up", "Hop - PARA");
a("Alt-Down", "Hop + PARA");
a("INSERT", "Insert", nchar);
a("Tab", "Mode 0 CHAR", nchar);
/*
curAct = npara;
a("MouseClicked1", "MouseSetCursor 0 PARA");
a("Backspace", "BackSpace 0 PARA");
a("Delete", "Delete 0 PARA");
a("Alt-Backspace", "Delete 0 PARA");
a("Left", "Cursor - PARA");
a("Right", "Cursor + PARA");
a("Shift-Left", "AdjLeft - PARA");
a("Shift-Right", "AdjRight + PARA");
a("Ctrl-Left", "AdjRight - PARA");
a("Ctrl-Right", "AdjLeft + PARA");
a("Alt-Left", "Hop - PARA");
a("Alt-Right", "Hop + PARA");
a("INSERT", "Insert");
a("Tab", "Mode 0 CHAR", nchar);
*/
curAct = nchar;
a("MouseClicked1", "MouseSetCursor 0 CHAR");
a("Left", "Cursor - CHAR");
a("Right", "Cursor + CHAR");
a("Backspace", "BackSpace 0 CHAR");
a("Delete", "Delete 0 CHAR");
a("Alt-Backspace", "Delete 0 CHAR");
a("INSERT", "Insert");
a("Tab", "Mode 0 WORD", nword);
a("Enter", "BreakParagraph 0 CHAR");
a("Ctrl-C", "PUICopy 0 CHAR");
a("Up", "Cursor - WORD");
a("Down", "Cursor + WORD");
}
static String[][] actions = {
{ "MouseClicked1", "Nile1.MouseSetCursor" },
{ "Left", "Nile1.Cursor -" },
{ "Right", "Nile1.Cursor +" },
{ "Shift-Left", "Nile1.AdjLeft -" },
{ "Shift-Right", "Nile1.AdjRight +" },
{ "Ctrl-Left", "Nile1.AdjRight -" },
{ "Ctrl-Right", "Nile1.AdjLeft +" },
{ "Alt-Left", "Nile1.Hop -" },
{ "Alt-Right", "Nile1.Hop +" },
{ "INSERT", "Nile1.Insert" }
};
}
// vim: set syntax=java :

View File

@@ -0,0 +1,71 @@
/*
Nile1Div.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.module;
import org.gzigzag.*;
import java.util.*;
/** A representation of a particular way of dividing up the nile stream.
* For instance, words, sentences, clauses, paragraphs or user-specified
* split points could be represented this way.
* It is allowed to have an non-zero-width break between the divisions.
* <p>
* It is assumed that no elements will be zero-width.
*/
public interface Nile1Div {
String rcsid = "$Id: Nile1Div.java,v 1.1 2000/11/20 17:36:13 tjl Exp $";
/** Find the next break.
* To iterate, over breaks, pass the start2 returned
* from the previous iteration
* as start to the next and set includeThis to false.
* <p>
* An important property here is that the stream may be cut
* at any location returned in end2.
*
* @param start The location to start from
* @param dir The direction to move into, 1 or -1.
* @param includeThis Whether to exclude the break where
* @param start2 The cursor to store the start of the next break in.
* @param end2 The cursor to store the end of the next break in.
* @return true if next break found.
*/
boolean findBreak(ZZCursor start,
int dir, boolean includeThis,
ZZCursor start2, ZZCursor end2);
/** Cut the stream at a boundary specified
* by this division.
* @param start An end of a break. This MUST have been returned by
* findBreak as start2 or end2.
*/
/** Splice two pieces of the stream, so that between them a division
* of this level is maintained.
*/
ZZCell splice(ZZCell p1, ZZCell p2);
}

View File

@@ -0,0 +1,81 @@
/*
Nile1GenTreeModel.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.module;
import org.gzigzag.*;
import java.util.*;
/** The nile1 structural model for GenTreePart.
* This implements the nile1 structural model from H1 to P levels as a
* tree using GenTreePart.
* @see GenTreePart
*/
public class Nile1GenTreeModel implements GenTreePartModel {
public static final String rcsid = "$Id: Nile1GenTreeModel.java,v 1.3 2000/11/22 00:35:41 tjl Exp $";
public static boolean dbg = true;
final static void p(String s) { if(dbg) System.out.println(s); }
final static void pa(String s) { System.out.println(s); }
public int depth() {
return 7;
}
public int depth(ZZCell c) {
if(c.s("d.nile-struct", -1) == null) return -1;
return Nile1Ops.getLevel(c);
}
public ZZCell getNext(int mindepth, ZZCell c, int steps) {
if(steps == 0) return c;
c = c.s("d.nile-struct", -1);
int dir = (steps > 0 ? 1 : -1);
ZZCell lasthdr = null;
while(steps != 0 && c != null) {
c = c.s("d.nile", dir);
if(c == null) return null;
lasthdr = c.s("d.nile-struct", 1);
if(lasthdr == null) continue;
if(depth(lasthdr) < mindepth) continue;
steps -= dir;
}
if(c == null) return null;
return lasthdr;
}
public void disconnectNeg(ZZCell c) {
p("Model: disconnectneg "+c);
c.s("d.nile-struct", -1).disconnect("d.nile", -1);
}
public void connect(ZZCell c, ZZCell d) {
p("Model: connect "+c+" "+d);
c.s("d.nile-struct", -1).h("d.nile", 1).connect("d.nile",
d.s("d.nile-struct", -1));
}
public void setDepth(ZZCell c, int d) {
if(depth(c) < 0) return;
Nile1Ops.setLevel(c, d);
}
}

479
Modules/nile/Nile1Ops.java Normal file
View File

@@ -0,0 +1,479 @@
/*
Nile1Ops.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.module;
import org.gzigzag.*;
import java.util.*;
/** A library of routines for operating on Nile1 streams.
* @see Nile1
* @deprecated Use Nile2Ops.
*/
public abstract class Nile1Ops {
public static final String rcsid = "$Id: Nile1Ops.java,v 1.16 2000/12/07 00:37:19 tjl Exp $";
public static boolean dbg = true;
static void p(String s) { if(dbg) System.out.println(s); }
static void pa(String s) { System.out.println(s); }
/** Split the given cell into two at the offset offset.
* The original cell will remain the first.
* Returns the cell that is after the split.
* If offset is zero or greater than or equal to the number of characters
* in c, nothing is done and either the current cell or the next cell is
* returned.
* <p>
* The most special case involves doing this at the very end of the stream,
* in which case an empty new cell is created and returned.
* @param c The cursor to split at
* @param always Whether to split even if the offset is at the beginning
* or end of a cell. Used e.g. for inserting a paragraph.
* @return Never null.
*/
static public ZZCell split(ZZCursor c, boolean always) {
// XXX Adjust cursors!!!
ZZCell c0 = c.get();
int offs = c.getOffs();
if(always) {
ZZCell c1 = c0.N("d.nile");
String s = c0.getText();
c0.setText(s.substring(0, offs));
c1.setText(s.substring(offs));
return c1;
} else {
if(offs == 0) return c0;
if(offs == c0.getText().length())
return c0.getOrNewCell("d.nile");
return split(c, true);
}
}
/** Break a paragraph at the given position.
* Returns the first cell of the (possibly empty) new paragraph.
*/
static public ZZCell breakParagraph(ZZCursor c) {
ZZCell n = split(c, true);
if(n.s("d.nile-struct") != null)
throw new ZZError("split structure already!");
ZZCell str = n.N("d.nile-struct");
setStrLevel(str, 0);
return n;
}
/** Change the structural level of a paragraph.
* @param c Any cell in the paragraph - does not need to be the first.
* @param level The new level.
*/
static public void setLevel(ZZCell c, int level) {
ZZCell para = findStruct(c, -1, true);
ZZCell str = para.s("d.nile-struct");
if(str == null) return;
setStrLevel(str, level);
}
/** Get the level of a paragraph.
* @param c Any cell in the paragraph - does not need to be the first.
*/
static public int getLevel(ZZCell c) {
ZZCell para = findStruct(c, -1, true);
ZZCell str = para.s("d.nile-struct");
if(str == null) return 6;
return getStrLevel(str);
}
/** Insert the given string into the stream at cursor.
*/
static public void insert(ZZCursor c, String txt) {
throw new ZZError("Not implemented");
}
/** The level of structure the given structure cell is.
* Note that the levels are a bit interesting: it returns
* zero for paragraphs, 1 for H6, 2 for H5 and so on.
* -1 is returned for cells that are not at a structural border.
*/
static int getStrLevel(ZZCell str) {
String txt = str.getText();
if(txt.equals("MP")) // Middle of paragraph - special level.
return -1;
if(txt.equals("P"))
return 0;
if(txt.equals("H1"))
return 6;
if(txt.equals("H2"))
return 5;
if(txt.equals("H3"))
return 4;
if(txt.equals("H4"))
return 3;
if(txt.equals("H5"))
return 2;
if(txt.equals("H6"))
return 1;
throw new ZZError("Invalid nile-struct "+txt);
}
static String[] levels = new String[] {
"P", "H6", "H5", "H4", "H3", "H2", "H1"
};
/** Set the level of a structural cell.
*/
static void setStrLevel(ZZCell str, int level) {
if(level < 0 || level > levels.length)
throw new ZZError("Request to set invalid level! "+level);
str.setText(levels[level]);
}
/** Find an angle in the rank, i.e.the next cell on a rank with
* a connection into a certain direction.
*/
static ZZCell findAngle(ZZCell c, String dim, int dir,
String adim, int adir, boolean includeThis) {
LoopDetector ld = new LoopDetector();
if(includeThis && c.s(adim, adir) != null) return c;
c = c.s(dim, dir);
while(c != null) {
if(c.s(adim, adir) != null) return c;
ld.detect(c);
c = c.s(dim, dir);
}
return null;
}
/** Find the next or previous cell that is a structural level element.
*/
static ZZCell findStruct(ZZCell c, int dir, boolean includeThis) {
ZZCell ret = findAngle(c, "d.nile", dir, "d.nile-struct", 1, includeThis);
if(ret == null && dir == -1) {
if(!includeThis && c.s("d.nile", -1) == null)
return null;
return c.h("d.nile", -1);
}
return ret;
}
/** An editing mode, i.e.the definition of what are the breaks
* that are being operated on in this mode.
*/
public interface Mode {
/** Set the mode cursor, and possibly selection cursor, to the
* given cursor.
* This is called in response to e.g. mouse click, so the position
* may be adjusted to the beginning of the previous unit.
*/
void setCursor(ZZCell view, ZZCursor c);
/** Move the cursor nsteps units.
*/
void moveCursor(ZZCell view, int nsteps);
/** Extend/shrink the selection by n units in given direction.
*/
void adjust(ZZCell view, int end, int nsteps);
/** Hop the selection.
*/
void hop(ZZCell view, int nsteps);
/** Delete the current selection, move cursor backwards or forwerds.
*/
// void delete(ZZCell view, int movedir);
}
public static class EdgeMode implements Mode {
Nile1Text.Edger edger;
EdgeMode(Nile1Text.Edger edger) { this.edger = edger; }
public void setCursor(ZZCell view, ZZCursor c) {
Stream.Iterator iter = giter(c);
edger.edge(iter, true, -1, Nile1Text.START);
curs(view).set(iter.get());
edger.edge(iter, false, 1, Nile1Text.END);
endcurs(view).set(iter.get());
}
// Move from end of area if forwards, from start if backwards.
public void moveCursor(ZZCell view, int nsteps) {
if(nsteps <= 0) {
Stream.Iterator iter = giter(curs(view));
if(!edger.edge(iter, false, nsteps, Nile1Text.START))
return;
curs(view).set(iter.get());
edger.edge(iter, false, 1, Nile1Text.END);
endcurs(view).set(iter.get());
} else {
Stream.Iterator iter = giter(endcurs(view));
if(!edger.edge(iter, false, nsteps, Nile1Text.END))
return;
endcurs(view).set(iter.get());
edger.edge(iter, false, -1, Nile1Text.START);
curs(view).set(iter.get());
}
}
public void adjust(ZZCell view, int end, int nsteps) {
ZZCursor c1 = curs(view);
ZZCursor c2 = endcurs(view);
if(end < 0) {
Stream.Iterator iter = Stream.getIterator(c1, "d.nile");
if(!edger.edge(iter, false, nsteps, Nile1Text.START))
return;
ZZCursor curs = iter.get();
if(!isOrdered(curs, c2)) return;
c1.set(curs);
} else {
Stream.Iterator iter = Stream.getIterator(c2, "d.nile");
if(!edger.edge(iter, false, nsteps, Nile1Text.END))
return;
ZZCursor curs = iter.get();
if(!isOrdered(c1, curs)) return;
c2.set(curs);
}
// XXX Check that they do not cross...
}
public void hop(ZZCell view, int nsteps) {
p("Cut out the selection for hop");
ZZCell selec = cutSelection(view);
if(selec == null) return;
ZZCursor c1 = curs(view);
p("Now, find place to paste at hopped location");
Stream.Iterator iter = Stream.getIterator(c1, "d.nile");
edger.edge(iter, false, nsteps, Nile1Text.START);
c1.set(iter.get());
p("And paste");
paste(view, selec, true);
}
}
static Mode wordmode = new EdgeMode(new Nile1Text.WordEdger());
static Mode sentencemode = new EdgeMode(new Nile1Text.SentenceEdger());
static public Mode getMode(ZZCell view) {
// return wordmode;
return sentencemode;
}
// XXX
static ZZCell adjStart(ZZCell c, int adj) {
if(adj > 0) {
// XXX Easily screws up font change!
ZZCursor c1 = new ZZCursorVirtual(c, 0);
if(!Stream.move(c1, "d.nile", adj))
throw new ZZError("ARRRRGH!");
if(c1.get().equals(c)) {
c.setText(c.getText().substring(adj));
} else {
c = split(c1, false);
c.disconnect("d.nile", -1);
}
} else if(adj < 0) {
// XXX Spans
String s = "";
while(adj++ < 0) s = s + " "; // XXX
ZZCell n = c.N("d.nile", -1);
n.setText(s);
}
return c;
}
static ZZCell adjEnd(ZZCell c, int adj) {
if(adj > 0) {
ZZCursor c1 = new ZZCursorVirtual(c, c.getText().length());
if(!Stream.move(c1, "d.nile", -adj))
throw new ZZError("ARRRRGH!");
// XXX
c = c1.get();
c.setText(c.getText().substring(0, c1.getOffs()));
c.disconnect("d.nile", 1);
} else if(adj < 0) {
c.setText(c.getText()+" ");
}
return c;
}
static void adjustSelection(Stream.Iterator start, Stream.Iterator end) {
Nile1Text.wordEdge(start, true, 1, Nile1Text.START);
Nile1Text.wordEdge(end, true, -1, Nile1Text.END);
}
static ZZCell cutSelection(ZZCell view) {
ZZCursor curs1 = curs(view);
p("Cut");
dump(curs1.get());
ZZCursor curs2 = endcurs(view);
if(!isOrdered(curs1, curs2)) return null;
Stream.Iterator iter1 = Stream.getIterator(curs1, "d.nile");
Stream.Iterator iter2 = Stream.getIterator(curs2, "d.nile");
int[] adj = new int[2];
Nile1Text.adjustCut(iter1, iter2, adj);
ZZCursor c1 = iter1.get();
ZZCursor c2 = iter2.get();
ZZCell after = split(c2, false);
p("\nAFTER SPLIT:");
dump(after);
ZZCell first = split(c1, false);
p("\nFIRST SPLIT:");
dump(first);
ZZCell prev = first.s("d.nile", -1);
ZZCell last = after.s("d.nile", -1);
after.disconnect("d.nile", -1);
first.disconnect("d.nile", -1);
if(prev != null) prev.connect("d.nile", after);
p("AFTER RECONNECT");
dump(prev);
curs(view).set(after);
curs(view).setOffs(0);
// Now, if more characters need to be left out, do it.
first = adjStart(first, adj[0]);
last = adjEnd(last, adj[1]);
if(adj[1] != 0) throw new ZZError("End adj not implemented");
p("AFTER CUTADJ");
dump(first);
return first;
}
/** Paste the given stream into the given cursor.
* The range and the text are adjusted for word-by-word
* insertion.
* @param view The viewcell that gives the location to
* paste into. Used later to set the new range,
* if desired.
* @param what The first cell of the stream to paste in.
* @param setRange Whether to set the selection of the given
* view to the pasted range afterwards.
*/
static void paste(ZZCell view, ZZCell what, boolean setRange) {
ZZCursor v = curs(view);
p("PASTE");
dump(v.get());
p("PASTING WHAT");
dump(what);
int[] adj = new int[2];
Stream.Iterator to = Stream.getIterator(v, "d.nile");
Stream.Iterator start = giter(new ZZCursorVirtual(what, 0));
ZZCell last = what.h("d.nile", 1);
Stream.Iterator end = giter(new ZZCursorVirtual(last,
last.getText().length()));
Nile1Text.adjustPaste(to, start, end, adj);
what = adjStart(start.get().get(), adj[0]);
adjEnd(end.get().get(), adj[1]);
p("WHAT ADJUSTED");
dump(what);
ZZCell after = split(v, false);
ZZCell before = after.s("d.nile", -1);
after.disconnect("d.nile", -1);
after.connect("d.nile", -1, what.h("d.nile", 1));
if(before != null)
before.connect("d.nile", 1, what);
if(setRange) {
v.set(what);
v.setOffs(0);
start = giter(v);
ZZCursor ev = endcurs(view);
ev.set(after);
ev.setOffs(0);
end = giter(ev);
adjustSelection(start, end);
v.set(start.get());
ev.set(end.get());
}
p("AFTER EVERYTHING");
dump(what);
}
// XXX Should use the tree for help...
static public boolean isOrdered(ZZCursor cu1, ZZCursor cu2) {
ZZCell c1 = cu1.get();
ZZCell c2 = cu2.get();
if(c1 == null || c2 == null) return false;
if(c1.equals(c2))
return cu1.getOffs() <= cu2.getOffs();
for(; c1 != null && !c1.equals(c2); c1 = c1.s("d.nile"));
if(c1 == null) return false;
return (c1.equals(c2));
}
// Shorthand...
static public ZZCursorReal curs(ZZCell view) {
return new ZZCursorReal(view);
}
static public Stream.Iterator giter(ZZCursor c) {
return Stream.getIterator(c, "d.nile");
}
static public ZZCursorReal endcurs(ZZCell view) {
ZZCell end = view.getOrNewCell("d.nile-sel");
return new ZZCursorReal(end);
}
static public void dump(ZZCell start) {
if(start == null) {
pa("Nile stream Null start!");
return;
}
ZZCell init = start.h("d.nile", -1);
pa("Nile stream! "+start);
boolean first = true;
for(ZZCell c = init; c != null; c=c.s("d.nile")) {
pa((c.s("d.nile-struct") != null ? "***S*** " : " ") +
" Cell "+c+" "+
(c.equals(start) ? " <----------------START" : ""));
if(!first && c.equals(init)) {
pa(" WAS A LOOOOOOOP!!!!!!!!!!");
throw new ZZFatalError("LOOPING NILE STREAM! BAD BAD TROUBLE!");
}
first = false;
}
}
}

356
Modules/nile/Nile1Text.java Normal file
View File

@@ -0,0 +1,356 @@
/*
Nile1Text.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.module;
import org.gzigzag.*;
import java.util.*;
/** A library of routines for operating on streams with Nile1 text model.
* @see Nile1
* @deprecated Use Nile2Unit
*/
public abstract class Nile1Text {
public static final String rcsid = "$Id: Nile1Text.java,v 1.9 2000/12/07 00:37:19 tjl Exp $";
public static boolean dbg = true;
static void p(String s) { if(dbg) System.out.println(s); }
static void pa(String s) { System.out.println(s); }
// Stream.Iterator iter = Stream.getIterator(start, "d.nile");
static public int START = 1;
static public int END = -1;
static public int ANY = 0;
static boolean isWordBreak(Stream.Iterator iter, int edge) {
char cur = iter.getChar();
if(cur == -1) return true;
if(!iter.move(-1)) return true;
char prev = iter.getChar();
iter.move(1);
return isWordBreak(prev, cur, edge);
}
static boolean isWordBreak(char prev, char cur, int edge) {
boolean ret = isWordBreak0(prev, cur, edge);
p("IsWordBreak: '"+prev+"' '"+cur+"' "+edge+ " RETURNING: "+ret);
return ret;
}
static boolean isWordBreak0(char prev, char cur, int edge) {
boolean curlet = Character.isLetterOrDigit(cur);
boolean curws = Character.isWhitespace(cur);
boolean prevlet = Character.isLetterOrDigit(prev);
boolean prevws = Character.isWhitespace(prev);
if(!curlet && !curws) {
if(edge != END) return true; // punctuation -> break start
return prevlet || !prevws; // punct -> br end if prev ltr or punct
}
if(prevlet && curlet) return false;
if(prevlet && curws) return edge != START;
// --> prevlet == false
if(!prevws) { // previous was punctuation ->
if(edge != START) return true;
return curlet; // Starting edge only if this is a letter.
}
if(prevws && curws) return false;
if(prevws && curlet) return edge != END;
// shouldn't get here
throw new ZZError("isWordBreak logic error!");
}
/** Find the nsteps:th next wordbreak.
* Always alters iter.
* <p>
* Characters are split into three categories:
* letter-or-digit, whitespace and other.
* whitespace is always a word boundary (but there is no
* word boundary between two whitespace characters).
* The characters in the other category are words by themselves.
* So basically there is a word break at character c, if
* <ul>
* <li> c is the first character in the stream.
* <li> c is one beyond the last character in the stream
* <li> c is punctuation
* <li> c is of a different category (see above) than
* the character just before it.
* </ul>
* @param nsteps The number of steps, a positive or negative number.
* @param edge Which edge of the word do we want: START, END or ANY.
*/
static public boolean wordEdge(Stream.Iterator iter,
boolean includeThis, int nsteps,
int edge) {
if(nsteps == 0) throw new ZZError("Can't step 0 words");
int dir = (nsteps > 0 ? 1 : -1);
for(; nsteps != 0; nsteps -= dir) {
if(!wordEdge0(iter, includeThis, dir, edge))
return false;
includeThis = false;
}
return true;
}
static private boolean wordEdge0(Stream.Iterator iter,
boolean includeThis, int dir,
int edge) {
char prev = 0;
char cur = iter.getChar();
if(dir > 0) {
if(includeThis) {
if(!iter.move(-dir)) return true;
prev = iter.getChar();
iter.move(dir);
if(isWordBreak(prev, cur, edge)) return true;
}
while(iter.move(dir)) {
prev = cur;
cur = iter.getChar();
if(cur == -1) return true; // Ran into end of text.
if(isWordBreak(prev, cur, edge)) return true;
}
return (edge != START);
} else {
if(!includeThis) {
if(!iter.move(dir)) return false;
cur = iter.getChar();
}
while(iter.move(dir)) {
prev = cur;
cur = iter.getChar();
if(isWordBreak(cur, prev, edge)) {
iter.move(-dir);
return true;
}
}
return (edge != END);
}
}
static public boolean sentenceEdge(Stream.Iterator iter,
boolean includeThis, int nsteps, int edge) {
if(nsteps == 0) throw new ZZError("Can't step 0 words");
int dir = (nsteps > 0 ? 1 : -1);
for(; nsteps != 0; nsteps -= dir) {
if(!sentenceEdge0(iter, includeThis, dir, edge))
return false;
includeThis = false;
}
return true;
}
static public boolean sentenceEdge0(Stream.Iterator iter,
boolean includeThis, int dir, int edge) {
if(edge == 0)
throw new ZZError("Looking for either sentence edge not implemented");
if(edge == START) {
// If we cannot move, we're at the beginning.
if(!iter.move(-1))
if(dir < 0 || includeThis) return includeThis;
// Back out
iter.move(1);
// Back up two, one by one, and then search non-inclusive.
iter.move(-1);
iter.move(-1);
if(iter.find(dir, includeThis, " ")) {
iter.move(2);
return true;
} else {
// There is a start in the beginning, but not at the end.
iter.end(dir);
return (dir < 0);
}
} else {
if(!iter.move(1)) return includeThis;
iter.move(-1);
// Here we just find because end is at the found text
if(iter.find(dir, includeThis, " "))
return true;
else {
iter.end(dir);
// There is an end in the end, but not at the beginning.
return (dir > 0);
}
}
}
static boolean ws(char c) { return Character.isWhitespace(c); }
static boolean punct(char c) {
return (!Character.isWhitespace(c)) && (!Character.isLetterOrDigit(c));
}
static boolean lett(char c) { return Character.isLetterOrDigit(c); }
/** Adjust the locations to cut text from.
* Basically, cut one or two spaces after the latter location,
* and if none, and there is a single space preceding,
* cut it along.
* <p>
* @param leaveout An output parameter: the values in the two-member
* array are set to the number of characters
* to leave out of the cut text.
* An important meaning is given to negative
* values: a negative value means "add this many
* spaces".
*/
static public void adjustCut(Stream.Iterator iter1,
Stream.Iterator iter2,
int[] leaveout) {
leaveout[0] = leaveout[1] = 0;
// First off, do not adjust if one of them is not word end.
if(!isWordBreak(iter1, START) || !(isWordBreak(iter2, END))) return;
char c1 = iter2.getChar(0);
char c2 = iter2.getChar(1);
// If there are one or two spaces afterwards, cut them along.
if(ws(c1)) {
iter2.move(1);
if(ws(c2))
iter2.move(1);
} else {
// If there is one character before...
char b1 = iter1.getChar(-1);
char b2 = iter1.getChar(-2);
if(ws(b1) && !ws(b2)) {
// This is a tricky situation. What we have here is
// cutting off in
// word WORD, word
// without the comma.
// The space before WORD needs to be removed.
// This is what the leaveout means.
//
// Additionally, for pasting at the correct boundary
// to work right, we need to add a space *after* this
// word when pasting. See adjustPaste.
iter1.move(-1);
leaveout[0] = 1;
}
}
}
/** The adjustment to a paste operation.
* @param adjust Analogour to the leaveout parameter of
* adjustCut. Positive values mean
* leaving this many characters out
* and negative values mean
* adding that many spaces.
*/
static public void adjustPaste(Stream.Iterator to,
Stream.Iterator start,
Stream.Iterator end,
int[] adjust) {
adjust[0] = adjust[1] = 0;
if(!isWordBreak(to, START)) return;
// If to is at a letter-punct edge, make sure
// pasted text starts with space and does not end with one.
// Otherwise, make sure it ends with space but doesn't start
// with it.
char c1 = to.getChar(-1);
char c2 = to.getChar(0);
if(lett(c1) && punct(c2)) {
// Now, start but don't end with space.
if(!ws(start.getChar(0))) adjust[0] = -1;
if(ws(end.getChar(-1))) adjust[1] = 1;
} else {
if(ws(start.getChar(0))) adjust[0] = 1;
if(!ws(end.getChar(-1))) adjust[1] = -1;
}
}
static public boolean paragraphEdge(Stream.Iterator iter,
boolean includeThis, int nsteps, int edge) {
if(nsteps == 0) throw new ZZError("Can't step 0 paragraphs");
int dir = (nsteps > 0 ? 1 : -1);
for(; nsteps != 0; nsteps -= dir) {
if(!paragraphEdge0(iter, includeThis, dir, edge))
return false;
includeThis = false;
}
return true;
}
static public boolean paragraphEdge0(Stream.Iterator iter,
boolean includeThis, int dir, int edge) {
ZZCell c = iter.get().get();
int offs = iter.get().getOffs();
boolean beg = (offs == 0);
boolean end = (offs == c.getText().length());
if(edge == 0)
throw new ZZError("Can't look for paragraph end / begin");
// XXX Should we set the end edge to point to negative
// direction?
// if(edge == START) {
if(dir > 0) {
if(!beg || !includeThis) c = c.s("d.nile");
} else {
if(beg && !includeThis) c = c.s("d.nile", -1);
}
// Now we can go on, using includeThis always.
if(c == null) return false;
c = Nile1Ops.findStruct(c, dir, true);
if(c != null) {
iter.set(new ZZCursorVirtual(c, 0));
if(edge == START)
iter.move(0, 1);
else
iter.move(0, -1);
return true;
} else {
if(edge == END && dir > 0) {
iter.end(); return true;
}
return false;
}
// }
}
public interface Edger {
boolean edge(Stream.Iterator iter, boolean includeThis, int nsteps,
int whichEdge);
}
static public class WordEdger implements Edger {
public boolean edge(Stream.Iterator iter, boolean includeThis,
int nsteps, int whichEdge) {
return wordEdge(iter, includeThis, nsteps, whichEdge);
}
}
static public class SentenceEdger implements Edger {
public boolean edge(Stream.Iterator iter, boolean includeThis,
int nsteps, int whichEdge) {
return sentenceEdge(iter, includeThis, nsteps, whichEdge);
}
}
static public class ParagraphEdger implements Edger {
public boolean edge(Stream.Iterator iter, boolean includeThis,
int nsteps, int whichEdge) {
return paragraphEdge(iter, includeThis, nsteps, whichEdge);
}
}
}

311
Modules/nile/Nile1View.zob Normal file
View File

@@ -0,0 +1,311 @@
/*
Nile1View.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.module;
import org.gzigzag.*;
import java.util.*;
import java.awt.*;
import java.io.*;
/** A view for nile streams.
*/
public class Nile1View implements FlobView, ZOb {
public static final String rcsid = "$Id: Nile1View.zob,v 1.4 2001/01/26 13:53: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); }
STRUCTPARAMS {
/** The default font to use.
*/
Font font
= new Font("SansSerif", Font.PLAIN, 11);
/** The distance between paragraphs.
*/
int paraskip
= 8;
/** The left-side margin for normal text.
* Headings hang left of this margin.
*/
int lmargin
= 50;
ZOb ftextlayouter
= new FTextLayouter();
/** Whether to use a special color for span (transcluded) cells. */
boolean showcopy
= false;
}
/** Bold and italic derivatives of the font given.
* The first index is the level of the text i.e.
* from paragraph to H1.
*/
Font[][][] bifonts;
FontMetrics[][][] bifontms;
INITIALIZE {
bifonts = new Font[7][2][2];
bifontms = new FontMetrics[7][2][2];
for(int l = 0; l < bifonts.length; l++) {
int size = font.getSize();
if(l > 0 && l < 5) size += l-1;
if(l == 5) size += 6;
if(l == 6) size += 9;
bifonts[l][1][0] = new Font(font.getName(),
Font.BOLD, size);
bifonts[l][1][1] = new Font(font.getName(),
Font.BOLD | Font.ITALIC, size);
if(l == 0) {
bifonts[l][0][0] = new Font(font.getName(), 0, size);
bifonts[l][0][1] = new Font(font.getName(),
Font.ITALIC, size);
} else { // All bold for headers
bifonts[l][0][0] = bifonts[l][1][0];
bifonts[l][0][1] = bifonts[l][1][1];
}
for(int b = 0; b<2; b++)
for(int i = 0; i<2; i++)
bifontms[l][b][i] = FONTMETRICS(bifonts[l][b][i]);
}
}
Color selcolor = Color.white;
Color copycolor = Color.yellow.darker().darker().darker().darker();
/** Return the formatted text object for one paragraph.
*/
FText paragraph(ZZCell start, ZZCell endBefore, ZZCursor offsetOfC,
int[]into,
ZZCursor selectEnd)
{
p("Paragraph! "+start+" "+endBefore+" ");
ZZCell selsc = null;
int selso = 0;
if(offsetOfC != null) {
selsc = offsetOfC.get();
selso = offsetOfC.getOffs();
}
ZZCell offsetOf = selsc;
ZZCell selec = null;
int seleo = 0;
if(selectEnd != null) {
selec = selectEnd.get();
seleo = selectEnd.getOffs();
}
boolean selected = (selsc == null && selec != null);
if(selso == ZZCursor.NO_OFFSET || selec == null) {
selsc = null;
selec = null;
selected = false;
}
FText.Part part = null;
int level = Nile2Iter.getLevel(start);
int curOffs = 0;
int b = 0, i = 0;
Vector parts = new Vector();
LoopDetector ld = new LoopDetector();
LoopDetector ld2 = new LoopDetector();
for(ZZCell c = start; c != null && c != endBefore; c = c.s("d.nile")) {
ld.detect(c);
for(ZZCell fs = c.s("d.nile-fmt-start"); fs != null;
fs = fs.s("d.nile-fmt-start")) {
ld.detect(fs);
if(fs.getText().equals("B")) b++;
else if(fs.getText().equals("I")) i++;
else p("Invalid format: "+fs.getText());
}
int b0 = (b > 0 ? 1 : 0);
int i0 = (i > 0 ? 1 : 0);
int len = c.getText().length();
if(c == offsetOf && into != null) into[0] = curOffs;
int internoffs = 0;
if(c == selsc) {
if(selso > len) {
ZZLogger.log("Warning: start over length "+selso+" "+len);
selso = len;
}
part = new FText.CellPart( c, 0, selso,
bifonts[level][b0][i0], bifontms[level][b0][i0],
null, c.getSpan() == null ? null : copycolor);
parts.addElement(part);
internoffs = selso;
selected = true;
p("Start selection: "+selso+" "+selsc);
}
if(c == selec && seleo >= internoffs) {
if(seleo > len) {
ZZLogger.log("Warning: end over length "+seleo+" "+len);
seleo = len;
}
part = new FText.CellPart( c, internoffs, seleo-internoffs,
bifonts[level][b0][i0], bifontms[level][b0][i0],
selcolor, c.getSpan() == null ? null : copycolor);
parts.addElement(part);
internoffs = seleo;
selected = false;
selectEnd.set((ZZCell)null);
p("End selection: "+seleo+" "+selec);
}
part = new FText.CellPart( c, internoffs, len-internoffs,
bifonts[level][b0][i0], bifontms[level][b0][i0],
selected ? selcolor : null,
c.getSpan() == null ? null : copycolor);
parts.addElement(part);
curOffs += len;
for(ZZCell fe = c.s("d.nile-fmt-end"); fe != null;
fe = fe.s("d.nile-fmt-start")) {
ld2.detect(fe); // Can't use same: same cell is start&end
if(fe.getText().equals("B")) b--;
else if(fe.getText().equals("I")) i--;
else p("Invalid format: "+fe.getText());
}
}
return new FText(parts);
}
Rectangle pmarg(Rectangle r, ZZCell para) {
int level = Nile2Iter.getLevel(para);
Rectangle ret = new Rectangle(r);
int w = (6 - level) * lmargin / 6;
ret.x += w; ret.width -= w;
return ret;
}
boolean[] beginningSentence = new boolean[2];
public Rectangle placeParagraph(FlobSet into,
FText ft, ZZCell para,Rectangle origrect,
int direction, int initY, int middleOffs) {
beginningSentence[0] = true;
beginningSentence[1] = false;
// Margins.
Rectangle rect = pmarg(origrect, para);
Rectangle ret = ((FTextLayouter)ftextlayouter).place(into, ft, rect,
1,
direction, initY, middleOffs, false,
beginningSentence);
// Now, do the cool thing with the section headings: include
// previous and next section headings of the same level here.
if(Nile2Iter.getLevel(para) > 0) {
ZZCell strcell = para.s("d.nile-struct");
if(strcell == null) return ret;
for(int dir = -1; dir <= 1; dir += 2) {
ZZCell prevsec = strcell.s("nile1str:breadth",dir);
if(prevsec == null) continue;
prevsec = prevsec.h("nile1str:depth").s("d.nile-struct", -1);
if(prevsec == null) continue;
beginningSentence[0] = true;
beginningSentence[1] = false;
FText nft = paragraph(prevsec, Nile2Iter.findStruct(prevsec, 1, false),
null, null, null);
((FTextLayouter)ftextlayouter).place(into, nft, rect, 200,
dir, ret.y + (dir < 0 ? 0 : ret.height),
0, false, beginningSentence);
}
}
return ret;
}
public void raster(FlobSet into, FlobFactory fact,
ZZCell view, String[] dims, ZZCell accursed) {
int[] offs = new int[1];
LoopDetector ld = new LoopDetector();
ZZCursor selectEnd = null;
ZZCell sele = view.s("d.nile-sel");
if(sele != null) {
selectEnd = ZZCursorVirtual.createFromReal(sele);
}
// Do the center paragraph first.
ZZCell firstpara = Nile2Iter.findStruct(accursed, -1, true);
ZZCell nextpara = Nile2Iter.findStruct(accursed, 1, false);
FText ft = paragraph(firstpara, nextpara, new ZZCursorReal(view),
offs, selectEnd);
Dimension size = into.getSize();
Rectangle rect = new Rectangle(0, 0, size.width, size.height);
Rectangle ctr = placeParagraph(into, ft, firstpara, rect,
0, rect.y+rect.height/2,
ZZCursorReal.getVisualTextOffset(view));
// Go into positive direction.
Rectangle r = ctr;
while(nextpara != null) {
ld.detect(nextpara);
ZZCell next = Nile2Iter.findStruct(nextpara, 1, false);
ft = paragraph(nextpara, next, null, null, selectEnd);
r = placeParagraph(into, ft, nextpara, rect,
1, r.y+r.height + paraskip, 0);
nextpara = next;
if(r.y + r.height > size.height) break;
}
// And negative.
r = ctr;
while(true) {
ZZCell prev = firstpara;
firstpara = Nile2Iter.findStruct(firstpara, -1, false);
if(firstpara == null) break;
ld.detect(firstpara);
ft = paragraph(firstpara, prev, null, null, null);
beginningSentence[0] = true;
r = placeParagraph(into, ft, firstpara, rect,
-1, r.y - paraskip, 0);
if(r.y < 0) break;
}
// into.dump();
Flob cursf = into.findFlob(null, accursed);
// p("Cursf: "+cursf);
if(cursf != null)
((SplitCellFlob1)cursf).addCurs(into, ZZCursorReal.getOffs(view),
Color.red);
}
}
// vim: set syntax=java :

589
Modules/nile/Nile2Iter.java Normal file
View File

@@ -0,0 +1,589 @@
/*
Nile2Iter.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.module;
import org.gzigzag.*;
/** A character-level iterator object that knows about
* paragraphs for a Nile stream.
* This object explicitly assumes no modifications to the
* stream while it is working.
*/
public final class Nile2Iter implements Cloneable {
public static final String rcsid = "$Id: Nile2Iter.java,v 1.8 2000/12/20 22:26:35 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); }
private ZZCell c;
private int offs;
// Cache these for speed.
private String ctext;
private int clen;
private void load(ZZCell c) {
this.c = c;
ctext = c.getText();
clen = ctext.length();
}
private void load(ZZCell c, int offs) {
load(c);
if(offs == -1) this.offs = clen;
else this.offs = offs;
move(0);
}
private void reload() {
load(c);
move(0);
}
static private boolean isStruct(ZZCell c) {
if(c == null)
throw new ZZError("Null isStruct?");
return c.s("d.nile-struct") != null;
}
Nile2Iter() { }
public Nile2Iter(ZZCursor curs) { set(curs); }
public void set(ZZCursor curs) {
load(curs.get());
this.offs = curs.getOffs();
// Ensure positive bias.
move(0);
}
public void set(Nile2Iter iter) {
load(iter.c);
offs = iter.offs;
}
/** Move n characters forwards or backwards within the current
* paragraph.
* If the offset given is out of bounds, moves as far as possible
* and returns false, otherwise returns true.
*/
public boolean move(int n) {
n += offs;
offs = 0;
// Internally, we like to maintain positive bias always.
// Thus, the greater-OR-EQUALS sign.
while(n >= clen) {
n -= clen;
ZZCell nc = c.s("d.nile");
if(nc == null || isStruct(nc)) {
// Only situation for negative bias: end of paragraph.
offs = clen;
if(n > 0) return false;
return true;
}
load(nc);
}
while(n < 0) {
ZZCell nc = c.s("d.nile", -1);
if(nc == null || isStruct(nc)) {
offs = 0;
return false;
}
load(nc);
n += clen;
}
offs = n;
return true;
}
/** Get the character at current offset.
* Returns -1 if out of bounds.
*/
public int cur() {
if(offs >= clen || offs < 0) return -1;
return ctext.charAt(offs);
}
public int get() { return cur(); }
public int next() {
if(!move(1)) return -1;
return cur();
}
public int prev() {
if(!move(-1)) return -1;
return cur();
}
public int get(int at) {
ZZCell cache = c;
int offscache = offs;
int ret = -1;
if(move(at)) {
ret = cur();
}
if(c != cache)
load(cache);
offs = offscache;
return ret;
}
/** Move n paragraphs, moving as little as possible.
* This means that if we move backwards, we will be at the end
* of the paragraph and vice versa.
*/
public boolean shiftPara(int n) {
// XXX What about empty paragraphs? A LOT of trouble...
if(n == 0) return true;
int dir = (n > 0 ? 1 : -1);
ZZCell nc = c;
while(n != 0) {
nc = nc.s("d.nile", dir);
if(nc == null) return false;
if(isStruct(nc)) n -= dir;
}
// Now we are at the paragraph cell.
// Need to take one step.
nc = nc.s("d.nile", dir);
if(nc == null) {
return false; // XXX Should set position!
// throw new ZZError("AUGH! Para shifting null next");
}
load(nc);
offs = (dir < 0 ? clen : 0);
return true;
}
/** Shift to paragraph beginning or end.
*/
public boolean paraEnd(int dir) {
ZZCell nc = c;
ZZCell prev = nc;
while(nc != null && !isStruct(nc)) {
prev = nc;
nc = nc.s("d.nile", dir);
}
if(nc == null) {
nc = prev;
} else {
nc = nc.s("d.nile", -dir);
}
load(nc);
offs = (dir < 0 ? 0 : clen);
return true;
}
public void streamEnd(int dir) {
// XXX When going to beginning, may set pos to struct!
ZZCell h = c.h("d.nile", dir);
paraEnd(dir);
}
/** Get the current position with given bias.
* @param bias Whether we are looking into positive or negative
* direction. If the cursor is at an edge,
* this affects which cell is returned.
*/
public ZZCursor getCursor(int bias) {
// XXX Check para?
if(bias < 0 && offs == 0) {
ZZCell nc = c.s("d.nile", -1);
return new ZZCursorVirtual(nc, nc.getText().length());
}
return new ZZCursorVirtual(c, offs);
}
public ZZCursor getCursor() { return getCursor(1); }
/** Cut the stream at this location.
* This pointer remains pointing to the prior space,
* and it returns a iter at the beginning of the new stream.
*/
public Nile2Iter cut() {
move(0);
Nile2Iter ni = new Nile2Iter();
if(offs == 0) {
ZZCell prev = c.getOrNewCell("d.nile", -1);
prev.disconnect("d.nile", 1);
ni.load(c, 0);
load(prev);
offs = clen;
return ni;
}
if(offs == clen) { // must be very end.
ZZCell next = c.getOrNewCell("d.nile", 1);
ni.load(next, 0);
c.disconnect("d.nile", 1);
return ni;
}
ZZCell spl = split(c, offs, true);
c.disconnect("d.nile", 1);
reload();
ni.load(spl, 0);
return ni;
}
// XXX Cursors easily cut out!
public void join(Nile2Iter to) {
c.h("d.nile", 1).connect("d.nile", to.c.h("d.nile", -1));
reload();
}
public void adjustSpaceStart(int nstart) {
if(dbg) dumpStream();
Nile2Iter ctr = (Nile2Iter)clone();
int ncur = 0;
while(Nile2Unit.ws(ctr.get())) {
ncur ++; ctr.move(1);
}
if(nstart < ncur) {
move(ncur-nstart);
// XXX Cursors could go wild.
set(cut());
} else if(nstart > ncur) {
StringBuffer buf = new StringBuffer();
while(nstart-- > ncur) buf.append(' ');
ZZCell n = c.N("d.nile", -1);
n.setText(buf.toString());
load(n, 0);
}
}
public void adjustSpaceEnd(int nend) {
Nile2Iter ctr = (Nile2Iter)clone();
ctr.streamEnd(1);
int ncur = 0;
while(Nile2Unit.ws(ctr.get(-1))) {
ncur ++; ctr.move(-1);
}
if(nend < ncur) {
ctr.move(nend); // Move back forwards.
// XXX Cursors could go wild.
ctr.cut();
} else if(nend > ncur) {
StringBuffer buf = new StringBuffer();
while(nend-- > ncur) buf.append(' ');
ZZCell n = ctr.c.h("d.nile", 1).N("d.nile", 1);
n.setText(buf.toString());
}
if(dbg) dumpStream();
}
public void adjustSpaces(int nstart, int nend) {
p("Adjustspaces: "+nstart+" "+nend);
adjustSpaceStart(nstart);
adjustSpaceEnd(nend);
}
public Object clone() {
try {
return super.clone();
} catch(CloneNotSupportedException e) {
ZZLogger.exc(e);
return null;
}
}
public void dumpStream() {
pa("Dumping Nile2Iter stream: at offs: "+offs);
dump(c);
}
/** Returns true if this &lt;= it.
* Throws an error if not in same stream.
*/
public boolean isOrdered(Nile2Iter it) {
if(c.equals(it.c)) {
return offs <= it.offs;
} else {
if(c.findCell("d.nile", 1, it.c)) return true;
if(!c.findCell("d.nile", -1, it.c))
throw new ZZError("IsOrdered: not on same stream!");
return false;
}
}
public void insertInCell(String s) {
ZZCell spl = split(c, offs, true);
spl = spl.N("d.nile", -1);
spl.setText(s);
load(spl, -1);
}
public void insert(String str) {
ZZCell n = c;
if(isStruct(c)) {
load(c.s("d.nile"), -1);
ZZCell d = n.N("d.nile");
d.setText(str);
ZZLogger.log("AUGH! Insert at struct cell!");
// throw new ZZError("Inserting");
} else if((offs == 0 || offs == clen) && c.getSpan() == null) {
if(offs == clen) {
c.setText(c.getText() + str);
load(c, -1);
} else { // In this case, this iter doesn't move ;)
ZZCell prev = c.s("d.nile", -1);
if(isStruct(prev) || prev == null)
c.N("d.nile", -1).setText(str);
else
prev.setText(prev.getText() + str);
}
} else {
if(offs > 0 && offs < clen) split(c, offs, false);
ZZCell d = c.N("d.nile", offs > 0 ? 1 : -1);
d.setText(str);
load(d, -1);
}
}
/** Make a cell's content into a span. */
static public Span spanify(ZZCell c0) {
Span sp = c0.getSpan();
if(sp != null) return sp;
StringScroll sc = c0.getSpace().getStringScroll();
String s = c0.getText();
long soffs = sc.append(s);
sp = Span.create(
Address.scrollOffs(sc, soffs),
Address.scrollOffs(sc, soffs + s.length() - 1)
);
c0.setSpan(sp);
return sp;
}
/** Split the given cell into two at the offset offset.
* The original cell will remain the first.
* Returns the cell that is after the split.
* If offset is zero or greater than or equal to the number of characters
* in c, nothing is done and either the current cell or the next cell is
* returned.
* <p>
* The most special case involves doing this at the very end of the stream,
* in which case an empty new cell is created and returned.
* @param c The cursor to split at
* @param always Whether to split even if the offset is at the beginning
* or end of a cell. Used e.g. for inserting a paragraph.
* @return Never null.
*/
static public ZZCell split(ZZCell c0, int offs, boolean always) {
// XXX Adjust cursors!!!
if(always) {
ZZCell c1 = c0.N("d.nile");
if(c0.s("d.nile-transcluded") != null) {
c0.insert("d.nile-transcluded", 1, c1);
c0.insert("d.nile-transcluded-split", 1, c1);
}
Span sp = c0.getSpan();
if(sp == null) {
String s = c0.getText();
c0.setText(s.substring(0, offs));
c1.setText(s.substring(offs));
} else {
c0.setSpan(sp.subSpan(0, offs));
c1.setSpan(sp.subSpan(offs));
}
return c1;
} else {
if(offs == 0) return c0;
if(offs == c0.getText().length())
return c0.getOrNewCell("d.nile");
return split(c0, offs, true);
}
}
/** Internal convenience: make a connection and a ring if it isn't yet
* This is part of a cheat to make jumping between transclusions work:
* we connect all transclusions of a cell on d.nile-transcluded, even
* if the transcluded spans do not overlap, and jump between them.
* Works because currently, a cell can contain only one span.
* XXX what to do when splitting ???
* XXX if we cheat anyway, is it more appropriate to use zz clones?
*/
static private void transcluded(ZZCell from, ZZCell to) {
from.insert("d.nile-transcluded", 1, to);
if(from.s("d.nile-transcluded", -1) == null)
from.connect("d.nile-transcluded", -1, to);
}
/** Transcopy the part of the stream between two iters.
* Sets the iters to point to the beginning and the end of the transcopied
* stream.
*/
static public void copy(Nile2Iter start, Nile2Iter to) {
if(!start.isOrdered(to)) {
Nile2Iter tmp = to;
to = start; start = tmp;
}
// First, spanify all cells.
ZZCell d = start.c;
while(true) {
if(!isStruct(d)) spanify(d);
p("Spanified "+d+" is span "+d.getSpan());
if(d == to.c) break;
d = d.s("d.nile");
}
// Next, create the new stream.
ZZCell first, last;
if(start.c.equals(to.c)) {
first = start.c.N();
last = first;
first.setSpan(start.c.getSpan().subSpan(start.offs, to.offs));
transcluded(start.c, first);
} else {
first = start.c.N();
first.setSpan(start.c.getSpan().subSpan(start.offs));
transcluded(start.c, first);
ZZCell prev = first;
ZZCell here = start.c.s("d.nile");
while(here != to.c) {
prev = prev.N("d.nile");
prev.setSpan(here.getSpan());
transcluded(prev, here);
here = here.s("d.nile");
}
last = prev.N("d.nile");
last.setSpan(to.c.getSpan().subSpan(0, to.offs));
transcluded(to.c, last);
}
// Finally, set the iters.
start.set(new ZZCursorVirtual(first, 0));
to.set(new ZZCursorVirtual(last, last.getText().length() - 1));
}
static public void dump(ZZCell start) {
if(start == null) {
pa("Nile stream Null start!");
return;
}
ZZCell init = start.h("d.nile", -1);
pa("Nile stream! "+start);
boolean first = true;
for(ZZCell c = init; c != null; c=c.s("d.nile")) {
pa((c.s("d.nile-struct") != null ? "***S*** " : " ") +
" Cell "+c+" "+
(c.equals(start) ? " <----------------START" : ""));
if(!first && c.equals(init)) {
pa(" WAS A LOOOOOOOP!!!!!!!!!!");
throw new ZZFatalError("LOOPING NILE STREAM! BAD BAD TROUBLE!");
}
first = false;
}
}
static String[] levels = new String[] {
"P", "H3", "H2", "H1"
};
static int getMaxLevel() { return levels.length - 1; }
// XXX Should use clones.
/** Set the level of a structural cell.
*/
static void setStrLevel(ZZCell str, int level) {
if(level < 0 || level > levels.length)
throw new ZZError("Request to set invalid level! "+level);
str.setText(levels[level]);
}
/** The level of structure the given structure cell is.
* Note that the levels are a bit interesting: it returns
* zero for paragraphs, 1 for H6, 2 for H5 and so on.
* -1 is returned for cells that are not at a structural border.
*/
static int getStrLevel(ZZCell str) {
String txt = str.getText();
for(int i=0; i<levels.length; i++)
if(txt.equals(levels[i])) return i;
throw new ZZError("Invalid nile-struct "+txt);
}
/** Find an angle in the rank, i.e.the next cell on a rank with
* a connection into a certain direction.
*/
static ZZCell findAngle(ZZCell c, String dim, int dir,
String adim, int adir, boolean includeThis) {
LoopDetector ld = new LoopDetector();
if(includeThis && c.s(adim, adir) != null) return c;
c = c.s(dim, dir);
while(c != null) {
if(c.s(adim, adir) != null) return c;
ld.detect(c);
c = c.s(dim, dir);
}
return null;
}
/** Find the next or previous cell that is a structural level element.
*/
static ZZCell findStruct(ZZCell c, int dir, boolean includeThis) {
ZZCell ret = findAngle(c, "d.nile", dir, "d.nile-struct", 1, includeThis);
if(ret == null && dir == -1) {
if(!includeThis && c.s("d.nile", -1) == null)
return null;
return c.h("d.nile", -1);
}
return ret;
}
/** Break a paragraph at the given position.
* Sets this position to the first position in the possibly
* empty new paragraph.
*/
public void breakParagraph() {
ZZCell n = split(c, offs, true);
load(n, 0);
// INsert the real structural cell between.
n = n.N("d.nile", -1);
ZZCell str = n.N("d.nile-struct");
setStrLevel(str, 0); // XXX Lists...
}
/** Get the level of a paragraph.
* @param c Any cell in the paragraph - does not need to be the first.
*/
static public int getLevel(ZZCell c) {
ZZCell para = findStruct(c, -1, true);
ZZCell str = para.s("d.nile-struct");
if(str == null) return 6;
return getStrLevel(str);
}
}

254
Modules/nile/Nile2Ops.java Normal file
View File

@@ -0,0 +1,254 @@
/*
Nile2Ops.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.module;
import org.gzigzag.*;
import java.util.*;
/** A library of routines for operating on Nile streams.
* @see Nile1
*/
public abstract class Nile2Ops {
public static final String rcsid = "$Id: Nile2Ops.java,v 1.9 2001/01/26 13:53: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); }
// static Nile2Unit unit = new Nile2Unit.Sentence();
static public void saveCursor(ZZCell view) {
ZZCell s = view.getOrNewCell("d.nile-save", 1);
if(ZZCursorReal.get(s) == null)
ZZCursorReal.set(s, new ZZCursorReal(view));
}
static public void clearSavedCursor(ZZCell view) {
ZZCell s = view.getOrNewCell("d.nile-save", 1);
if(ZZCursorReal.get(s) != null)
ZZCursorReal.set(s, (ZZCell)null);
}
static public ZZCursor getSavedCursor(ZZCell view) {
ZZCell s = view.getOrNewCell("d.nile-save", 1);
return new ZZCursorReal(s);
}
static public void setCursor(Nile2Unit unit, ZZCell view, ZZCursor to) {
p("Set cursor: "+unit+" "+view+" "+to);
if(to == null) {
// Saves only when there is nothing there before.
saveCursor(view);
to = getSavedCursor(view);
} else {
clearSavedCursor(view);
}
Nile2Iter iter = giter(to);
unit.start(iter, -1, true);
curs(view).set(iter.getCursor());
unit.end(iter, 1, true);
endcurs(view).set(iter.getCursor());
}
static public void moveCursor(Nile2Unit unit, ZZCell view, int dir) {
clearSavedCursor(view);
Nile2Iter iter;
if(dir > 0) {
iter = giter(endcurs(view));
if(!unit.insertPos(iter, 1, true)) return;
} else {
iter = giter(curs(view));
if(!unit.insertPos(iter, -1, false)) return;
}
curs(view).set(iter.getCursor());
unit.end(iter, 1, false);
endcurs(view).set(iter.getCursor());
}
static public void adjust(Nile2Unit unit, ZZCell view, int end, int dir) {
clearSavedCursor(view);
Nile2Iter iter = giter(curs(view));
Nile2Iter enditer = giter(endcurs(view));
if(end > 0) {
if(!unit.end(enditer, dir, false)) return;
} else {
if(!unit.start(iter, dir, false)) return;
}
if(!iter.isOrdered(enditer))
return;
curs(view).set(iter.getCursor());
endcurs(view).set(enditer.getCursor());
}
static public void hop(Nile2Unit unit, ZZCell view, int dir) {
clearSavedCursor(view);
Nile2Iter iter = giter(curs(view));
Nile2Iter enditer = giter(endcurs(view));
// XXX Checkpoint for undo!
Nile2Iter pt = unit.cut(iter, enditer);
unit.insertPos(pt, dir, false);
unit.paste(pt, iter, enditer);
curs(view).set(iter.getCursor());
endcurs(view).set(enditer.getCursor());
}
/** Tunnel text from one nile window to another.
* The text can be copied or cut.
*/
static public void tunnel(Nile2Unit unit, ZZCell from, ZZCell to,
int dir, boolean copy) {
clearSavedCursor(from); clearSavedCursor(to);
Nile2Iter fiter = giter(curs(from));
Nile2Iter fenditer = giter(endcurs(from));
Nile2Iter titer = giter(curs(to));
Nile2Iter pt = null;
// XXX Checkpoint for undo!
if(copy)
unit.copy(fiter, fenditer);
else
pt = unit.cut(fiter, fenditer);
// Insert exactly where we are -- is this o.k.?
// unit.insertPos(titer, dir, true);
unit.paste(titer, fiter, fenditer);
curs(to).set(fiter.getCursor());
endcurs(to).set(fenditer.getCursor());
if(!copy) {
unit.start(pt, -1, false);
curs(from).set(pt.getCursor());
unit.end(pt, 1, true);
endcurs(from).set(pt.getCursor());
}
}
static public boolean insert(ZZCell view, String key) {
clearSavedCursor(view);
if(key == null)
return false;
if(key.length() != 1)
return false;
Nile2Iter it = giter(curs(view));
it.insert(key);
ZZCursor c = it.getCursor();
curs(view).set(c);
endcurs(view).set(c);
return true;
}
static public void backspace(Nile2Unit unit, ZZCell view) {
clearSavedCursor(view);
Nile2Iter iter = giter(curs(view));
if(!unit.insertPos(iter, -1, false)) return;
Nile2Iter enditer = (Nile2Iter)iter.clone();
if(!unit.end(enditer, 1, false)) return;
Nile2Iter cut = unit.cut(iter, enditer);
if(cut == null)
throw new ZZError("Couldn't cut!");
setCursor(unit, view, cut.getCursor());
}
static public void del(Nile2Unit unit, ZZCell view) {
// XXX if nothing is selected -- delete unit right from ins cursor
unit.cut(giter(curs(view)), giter(endcurs(view)));
}
static public void breakParagraph(Nile2Unit unit, ZZCell view) {
clearSavedCursor(view);
Nile2Iter it = giter(curs(view));
it.breakParagraph();
setCursor(unit, view, it.getCursor());
}
static public void traverseTranscopies(ZZCell view, int dir) {
clearSavedCursor(view);
ZZCell c0 = ZZCursorReal.get(view);
ZZCell c = c0.s("d.nile-transcluded");
if(c == null) {
ZZLogger.log("Could not traverse transcopies because accused cell "
+ "IS not transcopied");
return;
}
ZZCell h0 = c0.h("d.nile-transcluded-split", true);
if(h0 != null) { // jump over splits
while(h0.equals(c.h("d.nile-transcluded-split"))) {
if(c.equals(c0))
throw new ZZError("XXX! All transcluded cells are "
+ "splits of the same cell! HELP!");
c = c.s("d.nile-transcluded");
}
}
ZZCursorReal.setOffs(view, 0);
ZZCursorReal.set(view, c);
}
/** Get a whole Nile stream as a string, properly capitalized.
* Converts paragraph breaks (==struct cells) to double newlines.<br>
* XXX a) It's no good this calls Nile2View, and it's even worse it does
* *line-breaking* to capitalize! I.e. move capitalization elsewhere
* (ZZUtil)<br>
* XXX b) Do this for the text between two iters (a selection), not only
* for a whole stream.<br>
* XXX c) Does this belong in this class? (It seemed to fit?)
*
* @param inStream Some cell inside the stream to be read.
*/
static public String stringify(ZZCell inStream) {
ZZCell hd = inStream.h("d.nile");
Nile1View n1v = new Nile1View();
n1v.init__zob();
String s = "";
ZZCell tail = Nile2Iter.findStruct(hd, 1, false);
while(hd != null) {
FText ft = n1v.paragraph(hd, tail, null, null, null);
ft.capitalize();
s = s + FText.Part.join(ft.parts);
hd = tail;
if(hd != null) tail = Nile2Iter.findStruct(hd, 1, false);
s = s + "\n\n";
}
return s;
}
// Shorthand...
static public ZZCursorReal curs(ZZCell view) {
return new ZZCursorReal(view);
}
static public Nile2Iter giter(ZZCursor c) {
return new Nile2Iter(c);
}
static public ZZCursorReal endcurs(ZZCell view) {
ZZCell end = view.getOrNewCell("d.nile-sel");
return new ZZCursorReal(end);
}
}

152
Modules/nile/Nile2Test.java Normal file
View File

@@ -0,0 +1,152 @@
/*
Nile2Test.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.module;
import org.gzigzag.*;
/** Some simple tests for Nile.
*/
public final class Nile2Test {
public static final String rcsid = "$Id: Nile2Test.java,v 1.1 2000/12/07 00:37:19 tjl Exp $";
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); }
static final void pok(String id, boolean ok) {
if(ok) p("ok "+id);
else p("not ok "+id);
}
public static void main(String[] argv) {
ZZSpace z = new ZZDimSpace();
ZZCell home = z.getHomeCell();
ZZCell stream = home.N("d.1", 1);
stream.N("d.nile-struct", 1); // Beginning structural marker
stream = stream.N("d.nile", 1); // Can't be at same cell.
stream.setText("Hello world a! How's it going?");
Nile2Iter it = new Nile2Iter(new ZZCursorVirtual(stream, 4));
p("Got: "+it.get());
Nile2Iter nextpart = it.cut();
it.dumpStream();
nextpart.dumpStream();
p("Got: "+it.get());
pok("Atend", it.get() == -1);
pok("Prev", it.get(-1) == 'l');
pok("foll", nextpart.get() == 'o');
pok("atstart", nextpart.get(-1) == -1);
it.dumpStream();
p("Joining");
it.join(nextpart);
it.dumpStream();
nextpart.dumpStream();
pok("GET1", it.get() == 'o');
pok("NEXT1", it.next() == ' ');
pok("NEXT2", it.next() == 'w');
pok("PREV1", it.prev() == ' ');
// Next, test word boundaries.
Nile2Unit un = new Nile2Unit.Word();
pok("PREVWORD1", un.start(it, -1, false));
pok("PREVWORD2", !un.start(it, -1, false));
pok("Wordplace", it.get() == 'H' && it.get(1) == 'e');
pok("NEXTWORD1", un.start(it, 1, true));
pok("Wordplace2", it.get() == 'H' && it.get(1) == 'e');
pok("NEXTWORD2", un.start(it, 1, false));
pok("Wordplace3", it.get() == 'w' && it.get(1) == 'o');
pok("NEXTWORD2", un.start(it, 1, false));
pok("Wordplace2.5", it.get() == 'a' && it.get(1) == '!');
pok("NEXTWORD2", un.start(it, 1, false));
pok("Wordplace3", it.get() == '!' && it.get(1) == ' ');
pok("NEXTWORD3", un.start(it, 1, false));
pok("Wordplace4", it.get() == 'H' && it.get(1) == 'o');
Nile2Unit un2 = new Nile2Unit.Sentence();
pok("senst1", un2.start(it, -1, false));
pok("senst2", !un2.start(it, -1, false));
pok("Sen", it.get() == 'H' && it.get(1) == 'e');
pok("senst3", un2.start(it, 1, false));
pok("Sen", it.get() == 'H' && it.get(1) == 'o');
it.dumpStream();
pok("senst4", !un2.start(it, 1, false));
it.dumpStream();
pok("senst5", un2.start(it, -1, false));
pok("senst6", un2.start(it, -1, false));
pok("senst7", !un2.start(it, -1, false));
// Now at beginning.
Nile2Iter end = (Nile2Iter)it.clone();
pok("sene1", un2.end(end, 1, true));
p("At end: "+(end.get(-1))+"||"+end.get());
end.dumpStream();
pok("sene2", end.get() == ' ' && end.get(-1) == '!');
Nile2Iter result = un2.cut(it, end);
p("Start:");
it.dumpStream();
p("End:");
end.dumpStream();
p("Res:");
result.dumpStream();
// Next, test adjustspaces.
ZZCell n = stream.N("d.1", 1);
n.setText("d");
it.set(new ZZCursorVirtual(n, 0));
pok("as1", it.get(-1) == -1 && it.get() == 'd' && it.get(1) == -1);
it.adjustSpaces(0, 1);
p("Adjusted: ");
it.dumpStream();
pok("as2", it.get(-1) == -1 && it.get() == 'd' && it.get(1) == ' ');
it.adjustSpaces(0, 0);
p("Adjusted3: ");
it.dumpStream();
pok("as3", it.get(-1) == -1 && it.get() == 'd' && it.get(1) == -1);
it.adjustSpaces(1, 0);
pok("as4", it.get(-1) == -1 && it.get() == ' ' && it.get(1) == 'd'
&& it.get(2) == -1);
it.adjustSpaces(0, 0);
p("Adjusted5: ");
it.dumpStream();
pok("as5", it.get(-1) == -1 && it.get() == 'd' && it.get(1) == -1);
pok("END", true);
System.exit(0);
}
}

432
Modules/nile/Nile2Unit.java Normal file
View File

@@ -0,0 +1,432 @@
/*
Nile2Unit.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.module;
import org.gzigzag.*;
/** A nile unit of division.
*/
public abstract class Nile2Unit {
public static final String rcsid = "$Id: Nile2Unit.java,v 1.5 2000/12/17 16:32:24 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 previous or next position where
* this type of unit may be inserted.
*/
public abstract boolean insertPos(Nile2Iter iter, int dir,
boolean includeThis);
/** The previous or next beginning position of this type of
* unit.
*/
public abstract boolean start(Nile2Iter iter, int dir, boolean includeThis);
/** The previous or next ending position of this type of unit.
*/
public abstract boolean end(Nile2Iter iter, int dir, boolean includeThis);
/** Cut the stream.
* This routine modifies the start and to iterators to point
* to the beginning and end of the modified stream.
* @return The pasted-together cutaway point, from which
* the insert position can be searched with !includeThis.
*
*/
public abstract Nile2Iter cut(Nile2Iter start, Nile2Iter to);
/** Copy a part of the stream.
* First every cell is spanified, then a new stream with the same spans
* is created.
* This routine modifies the start and to iterators to point
* to the beginning and end of the copied stream.
* XXX any special copying rules to obey, like in cut?
*/
public void copy(Nile2Iter start, Nile2Iter to) {
this.start(start, -1, true);
this.end(to, 1, true);
Nile2Iter.copy(start, to);
}
public abstract void paste(Nile2Iter at, Nile2Iter what, Nile2Iter whatEnd);
static public class Char extends Nile2Unit {
public boolean insertPos(Nile2Iter iter, int dir,
boolean includeThis) {
if(!includeThis)
if(!iter.move(dir))
if(!iter.shiftPara(dir))
return false;
return true;
}
public boolean start(Nile2Iter iter, int dir,
boolean includeThis) {
if(!includeThis)
if(!iter.move(dir))
if(!iter.shiftPara(dir))
return false;
if(iter.get() == -1) return false;
return true;
}
public boolean end(Nile2Iter iter, int dir,
boolean includeThis) {
if(!includeThis)
if(!iter.move(dir))
if(!iter.shiftPara(dir))
return false;
if(iter.get(-1) == -1) return false;
return true;
}
public Nile2Iter cut(Nile2Iter start, Nile2Iter to) {
Nile2Iter after = to.cut();
start.cut();
start.join(after);
return start;
}
public void paste(Nile2Iter at, Nile2Iter what, Nile2Iter whatEnd) {
}
}
/** The word and sentence base class.
* Words and sentences obey the same rules for the insert point.
*/
static public abstract class WordOrsentence extends Nile2Unit {
public abstract boolean isStart(Nile2Iter iter);
public abstract boolean isEnd(Nile2Iter iter);
public abstract int nspacesAtEnd();
// As documented,
// word insert points are word starting points, as well as
// paragraph's ending points.
public boolean insertPos(Nile2Iter iter, int dir,
boolean includeThis) {
return startOrIns(iter, dir, includeThis, true);
}
public boolean start(Nile2Iter iter, int dir, boolean includeThis) {
return startOrIns(iter, dir, includeThis, false);
}
public boolean startOrIns(Nile2Iter iter, int dir, boolean includeThis,
boolean insert) {
// This way we can always assume includeThis later.
if(!includeThis)
if(!iter.move(dir)) {
if(!iter.shiftPara(dir))
return false;
// If we were looking for an insert point, we just
// found it...
if(dir < 0 && insert) return true;
}
// Can optimize if necessary...
while(true) {
if(isStart(iter)) return true;
if(!iter.move(dir)) {
if(dir > 0 && insert) return true;
if(!iter.shiftPara(dir)) return false;
if(dir < 0 && insert) return true;
}
}
}
public boolean end(Nile2Iter iter, int dir, boolean includeThis) {
if(!includeThis)
if(!iter.move(dir)) {
if(!iter.shiftPara(dir)) return false;
// In forwards dir, just go to the beginning
// of the next paragraph.
// This way, cutting from the last insertpos until
// end() results in just the paragraph break being
// removed, which is just right.
return true;
}
while(true) {
if(isEnd(iter)) return true;
if(!iter.move(dir))
if(!iter.shiftPara(dir))
return false;
}
}
public Nile2Iter cut(Nile2Iter start, Nile2Iter end) {
// Find first non-space character.
int nws = this.firstNonWs(start);
this.p("Cut Firstnonws: "+nws + " '"+(char)nws+"'");
boolean startPunct = this.punct(nws);
// cut all the space after end.
int ncut = 0;
Nile2Iter endclone = (Nile2Iter)end.clone();
while(this.ws(end.get())) { end.move(1); ncut ++; }
// If we happen to have space before us, count that too!
int nspace = 0;
while(this.ws(endclone.prev())) nspace++;
Nile2Iter rstart = null;
if(ncut + nspace == 0 || startPunct) {
// If no space at end,
// we must cut space from before this, if it
// is a single space.
if(this.ws(start.get(-1)) && !this.ws(start.get(-2)))
(rstart = (Nile2Iter)start.clone()). move(-1);
else
if(this.ws(start.get(-1)) && startPunct) {
(rstart = (Nile2Iter)start.clone()). move(-1);
// For the if down later
ncut = 1;
}
}
// Now, here's the cut. We take away the stuff from
// start to end and then remove from rstart
// We must cut starting from the end so as not to disturb
// things.
Nile2Iter after = end.cut();
Nile2Iter first = start.cut();
Nile2Iter before = (Nile2Iter)start.clone();
start.set(first); // We want to return this in start.
// Finally, cut the other stuff.
if(rstart != null) {
rstart.cut();
before = rstart;
}
before.join(after);
// This is a bit special rule.
if(startPunct && ncut + nspace > 0)
before.insertInCell(" ");
return before;
}
public void paste(Nile2Iter at, Nile2Iter what, Nile2Iter whatEnd) {
// Check whether what has punctuation in the start...
int nws = this.firstNonWs(what);
this.p("Paste Firstnonws: "+nws + " '"+(char)nws+"'");
boolean startPunct = this.punct(nws);
Nile2Iter after = null;
if(dbg) {
this.p("PASTE!!!");
at.dumpStream();
what.dumpStream();
}
if(startPunct) {
// If there is punctuation, we must start it with
// exactly the spaces that were there, UNLESS
// we are at the beginning of the sentence, in which
// case we shall have two spaces.
if(this.ws(at.get(-1)) && this.ws(at.get(-2))) {
// Ok, now it's difficult.
// Leave these spaces, but remove one in the
// beginning of
what.adjustSpaceStart(0);
after = at.cut();
} else {
if(this.ws(at.get(-1))) {
at.move(-1);
after = at.cut();
after.move(1);
after = after.cut();
} else {
after = at.cut();
}
}
} else {
// pasting words is a bit tricky.
int prev = at.get(-1);
int cur = at.get();
// Where do we want to ensure we have space.
boolean spaceEnd = false, spaceStart = false;
// If we are at start of paragraph, we ensure that
// a space is in the end.
if(prev == -1) spaceEnd = true;
else if(this.punct(cur)) {
// If we are at punctuation, we put a space after
// inserted text is there was a space before.
if(this.ws(prev)) spaceEnd = true;
else spaceStart = true;
}
else spaceEnd = true;
what.adjustSpaces(spaceStart ? 1 : 0,
spaceEnd ? nspacesAtEnd() : 0);
after = at.cut();
}
at.join(what);
whatEnd.set(what);
whatEnd.streamEnd(1);
whatEnd.join(after);
whatEnd.set(after);
}
}
static public class Word extends WordOrsentence {
public boolean isStart(Nile2Iter iter) { return this.isWordStart(iter); }
public boolean isEnd(Nile2Iter iter) { return this.isWordEnd(iter); }
public int nspacesAtEnd() { return 1; }
}
static public class Sentence extends WordOrsentence {
public boolean isStart(Nile2Iter iter) { return this.isSentenceStart(iter); }
public boolean isEnd(Nile2Iter iter) { return this.isSentenceEnd(iter); }
public int nspacesAtEnd() { return 2; }
}
static public class Paragraph extends Nile2Unit {
// A paragraph may be inserted at the end of any paragraph,
// or in the very beginning of the stream.
// That requires special handling because
// Nile2Iter can't get there.
public boolean insertPos(Nile2Iter iter, int dir,
boolean includeThis) {
// XXX First, check if we *are* there already.
if(!end(iter, dir, includeThis)) {
if(dir > 0) return false;
ZZCursor curs = iter.getCursor(1);
curs.set(curs.get().h("d.nile"));
curs.setOffs(0);
iter.set(curs);
}
return true;
}
public boolean start(Nile2Iter iter, int dir, boolean includeThis) {
if(!includeThis) {
if(!iter.move(dir)) {
// We were at the beginning
if(!iter.shiftPara(dir))
return false;
}
}
return iter.paraEnd(-1);
}
public boolean end(Nile2Iter iter, int dir, boolean includeThis) {
if(!includeThis) {
if(!iter.move(dir)) {
// We were at the beginning
if(!iter.shiftPara(dir))
return false;
}
}
return iter.paraEnd(1);
}
public Nile2Iter cut(Nile2Iter start, Nile2Iter end) {
return null;
}
public void paste(Nile2Iter at, Nile2Iter what, Nile2Iter whatEnd) {
}
}
// Something non-ws following to ws's.
static public boolean isSentenceStart(Nile2Iter iter) {
int cur = iter.get();
if(cur == -1 || ws(cur)) return false;
int prev = iter.get(-1);
if(prev == -1) return true;
if(!ws(prev)) return false;
int prev2 = iter.get(-2);
if(prev2 == -1) return true;
if(!ws(prev2)) return false;
return true;
}
// Something non-ws following to ws's.
static public boolean isSentenceEnd(Nile2Iter iter) {
int prev = iter.get(-1);
if(prev == -1 || ws(prev)) return false;
int cur = iter.get();
if(cur == -1) return true;
if(!ws(cur)) return false;
int next = iter.get(1);
if(next == -1) return true;
if(!ws(next)) return false;
return true;
}
static public boolean isWordStart(Nile2Iter iter) {
int cur = iter.get();
if(punct(cur)) {
/* if(lett(punct.get(-1)) && lett(punct.get(1))) {
// Punctuation surrounded by two letters is NOT
// a word boundary.
return false;
} else XXX Must test in other cases!!! */
return true;
}
int prev = iter.get(-1);
// This should also cover buffer start.
if(lett(cur) && !lett(prev)) return true;
return false;
}
static public boolean isWordEnd(Nile2Iter iter) {
int prev = iter.get(-1);
if(punct(prev))
/*
if(lett(punct.get(-2)) && lett(punct.get(0))) {
// Punctuation surrounded by two letters is NOT
// a word boundary.
return false;
} else XXX Must test!!!! */
return true;
int cur = iter.get();
if(lett(prev) && !lett(cur)) return true;
return false;
}
// Shorthand.
// Exactly one of these must return true for every character.
// except -1, when all are false.
static boolean ws(int c) { return Character.isWhitespace((char)c); }
static boolean punct(int c) {
if(c == -1) return false;
return (!Character.isWhitespace((char)c)) &&
(!Character.isLetterOrDigit((char)c));
}
static boolean lett(int c) { return Character.isLetterOrDigit((char)c); }
static int firstNonWs(Nile2Iter iter) {
int ch = 0;
// Use index, don't move.
for(int i=0; (ch=iter.get(i)) != -1; i++) {
if(!ws(ch)) return ch;
}
return -1;
}
}

View File

@@ -0,0 +1,63 @@
/*
NileApplet.java
*
* Copyright (c) 1999, 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.applet.*;
import java.io.*;
import java.util.*;
/** An applet showing the split Nile view.
* This just takes a lot of code from ZZApplet -- bad style. Well, this is
* just an intermediate: When we start making real demos using the Dump
* stuff, ZZApplet probably needs to be rewritten, and NileApplet will be
* totally obsolete.
*/
public class NileApplet extends Applet {
public static final String rcsid = "$Id: NileApplet.java,v 1.4 2001/01/03 16:47:50 raulir Exp $";
public void init() {
ZZSpace space = new ZZCacheDimSpace(new DummyStreamSet());
ZZCell home=space.getHomeCell();
home.N("d.1").setText("First text");
home.N("d.1").setText("Second text");
ZZDefaultSpace.create(home);
setLayout(new BorderLayout());
ZZWindows.init(space,this);
ZZCell topl = ZZWindows.startCell().s("d.1", 1)
.s("d.2", 1);
ZZCell a = topl.s("d.1", 2);
ZZCell b = topl.s("d.2", 1).s("d.1", 1);
ZZCursorReal.set(a, home.s("d.1", 1));
ZZCursorReal.set(b, home.s("d.1", 2));
ZZCursorReal.setColor(a,Color.red);
ZZCursorReal.setColor(b,Color.yellow);
org.gzigzag.module.SplitNileDemo.updateSpace(a, a, b);
ZZObsTrigger.runObsQueue();
}
}

143
Modules/nile/NileDemo.java Normal file
View File

@@ -0,0 +1,143 @@
/*
NileDemo.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.module;
import org.gzigzag.*;
import java.util.*;
import java.awt.*;
import java.io.*;
public class NileDemo {
public static final String rcsid = "$Id: NileDemo.java,v 1.3 2000/12/28 01:19:07 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); }
/** Update the bindings etc.in the space.
* This is temporary and should go away once we have better
* space management.
*/
static void updateSpace(ZZCell code, ZZCell viewCell, ZZCell ctrlCell) {
// First, make sure the system list cell is ok
// and recreate actions.
ZZSpace sp = code.getSpace();
ZZCell t0 = ZZDefaultSpace.findOnSystemlist(sp, "Nile1", true);
ZZCell bind = t0.getOrNewCell("d.1", 1);
ZZCell rast = t0.getOrNewCell("d.2", 1);
bind.disconnect("d.1", 1);
bind = bind.N("d.1", 1);
Nile1.actions(bind);
rast.disconnect("d.1",1);
rast = rast.N("d.1");
rast.setText("Nile1View");
rast = rast.N("d.1");
rast.setText("Nile1.Normal");
rast = rast.s("d.1", -1); // go to the cell we need
// Then, update windows.
ZZCell datac = updateWin(sp, viewCell, rast, bind, false);
ZZCell ctrlc = updateWin(sp, ctrlCell, rast, bind, true);
if(datac != null && ctrlc != null) {
datac.excise("d.nile-wins"); ctrlc.excise("d.nile-wins");
ctrlc.connect("d.nile-wins", 1, datac);
datac.connect("d.nile-wins", 1, ctrlc);
}
}
static ZZCell updateWin(ZZSpace sp, ZZCell viewCell, ZZCell rast,
ZZCell bind, boolean ctrl) {
if(viewCell == null) return null;
// Make sure we have a window and update its
// binding and raster.
ZZCell win = null;
String title = ctrl ? "Nile1-Left" : "Nile1W";
int round = 0;
while(win == null) {
if(round > 1)
throw new ZZError("Couldn't create window");
round++;
win = ZZDefaultSpace.findOnSystemlist(sp, "Windows", false);
win = win.s("d.1");
win = win.findText("d.2", 1, title);
if(win == null)
ZZDefaultSpace.newToplevelView(sp,
title, ctrl ? 0 : 400, 20, 400, 400,
null, null, null, viewCell,
null, new Color(0x819fff));
}
// Then, set window bindings
win = win.s("d.1", 2);
ZZCell bcurs = win.getOrNewCell("d.bind", 1);
ZZCursorReal.set(bcurs, bind);
ZZCell viewsel = win.findText("d.2", 1, "View");
ZZCursorReal.set(viewsel, rast);
ZZCursorReal.setColor(viewsel, ZZUtil.perturb(Color.red));
return win;
}
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) {
ZZUpdateManager.setFast(view);
ZZCell viewCell = view.getViewcell();
ZZCell otherCell = viewCell.s("d.nile-wins");
p("Nile action: "+id+" "+key);
StringTokenizer st = new StringTokenizer(id);
String[] toks = new String[st.countTokens()];
for(int i=0; i<toks.length; i++)
toks[i] = st.nextToken();
id = toks[0];
// Update the Nile stuff to the latest bindings (defined
// unfortunately in this file -- oh how I long for the day
// when they are in a ZZ space as the definitive version)
if(id.equals("UPDATE")) {
updateSpace(code, viewCell, null);
} else if(id.equals("UPDATEBOTH")) {
updateSpace(code, viewCell, cview.getViewcell());
} else if(id.equals("REGISTER")) {
ZZCell binds = code.N();
Nile1.actions(binds);
ApplitudeMgr.register(code.getSpace(), "Nile",
new String[] { "d.nile" },
"Nile1.Normal", binds);
}
}
};
}

49
Modules/nile/README Normal file
View File

@@ -0,0 +1,49 @@
Nile Is a Literary Editor ;)
=========================
Hierarchical text structure
Key-based simple selections *and* motions of the selected text
word-by-word, sentence-by-sentence.
Parallel markup stream, indicating the paragraphs and sectioning.
Additionally, spaceparts that use this markup to imply various
kinds of trees.
With firstcap after any two spaces.
Operations: (not yet implemented - this is a list of ideas)
Fundamental (required to create text that uses all features)
- insertion
- backspace, going over paragraph boundaries
- enter, split / start new paragraph
- cursor motion
- adjust paragraph level (P .. H1)
(XXX mustn't take too much keyspace if we want e.g. ULs later)
Rearrangement (the real thing)
- selecting groups by word / sentence / paragraph using keyboard,
hopping those bits over the corresponding bits
- easily moving to outline view, outline hop
- splitting into implied fragments and hopping those as cells
- cutting into textcloud -style bits that float around paragraphs
Hyperconnections
- paragraph comments for outline
- sideways connected documents, using nile-anchor dimension between
cells very simply. Like paralleltextview
Versioning & transcluding
- need cellular versioning mechanisms
- side-by-side view with beams
(the nile delta view ;)
- see all current documents that transclude given area
-----
Refs:
http://devworld.apple.com/techpubs/mac/HIGuidelines/HIGuidelines-224.html
http://www.windowatch.com/firstwords/fw-cutpa.html
http://www.windowatch.com/firstwords/first3.html
http://www.oasis-open.org/cover/coombs.html
Word's selection by words by default needs to be mentioned.

View File

@@ -0,0 +1,113 @@
/*
SplitNileDemo.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.module;
import org.gzigzag.*;
import java.util.*;
import java.awt.*;
import java.io.*;
public class SplitNileDemo {
public static final String rcsid = "$Id: SplitNileDemo.java,v 1.2 2000/12/26 21:59:22 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); }
/** Update the bindings etc.in the space.
* This is temporary and should go away once we have better
* space management.
*/
static public void updateSpace(ZZCell code, ZZCell viewCell,
ZZCell ctrlCell) {
// First, make sure the system list cell is ok
// and recreate actions.
ZZSpace sp = code.getSpace();
ZZCell t0 = ZZDefaultSpace.findOnSystemlist(sp, "SplitNile", true);
ZZCell bind = t0.getOrNewCell("d.1", 1);
ZZCell rast = t0.getOrNewCell("d.2", 1);
bind.disconnect("d.1", 1);
bind = bind.N("d.1", 1);
Nile1.actions(bind);
rast.disconnect("d.1",1);
rast = rast.N("d.1");
rast.setText("Nile1View");
rast = rast.N("d.1");
rast.setText("Nile1.Parallel");
rast = rast.s("d.1", -1); // go to the cell we need
// Next, make sure we have a window
ZZCell win = null;
String title = "Nile";
int round = 0;
while(win == null) {
if(round > 1)
throw new ZZError("Couldn't create window");
round++;
win = ZZDefaultSpace.findOnSystemlist(sp, "Windows", false);
win = win.s("d.1");
win = win.findText("d.2", 1, title);
if(win == null)
ZZDefaultSpace.newToplevelView(sp,
title, 20, 20, 600, 400,
null, null, null, null,
null, new Color(0x819fff));
}
// Then, create the cursor pair and set the window cursor
win = win.s("d.1", 2);
ZZCell leftcurs = win.N();
ZZCursorReal.attach(leftcurs, ctrlCell);
ZZCell rightcurs = leftcurs.N("d.nile-pair");
ZZCursorReal.attach(rightcurs, viewCell);
ZZCursorReal.set(win, leftcurs);
// Finally, set window bindings
ZZCell bcurs = win.getOrNewCell("d.bind", 1);
ZZCursorReal.set(bcurs, bind);
ZZCell viewsel = win.findText("d.2", 1, "View");
ZZCursorReal.set(viewsel, rast);
ZZCursorReal.setColor(viewsel, ZZUtil.perturb(Color.red));
}
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) {
ZZUpdateManager.setFast(view);
// Update the Nile stuff to the latest bindings (defined
// unfortunately in this file -- oh how I long for the day
// when they are in a ZZ space as the definitive version)
if(id.equals("UPDATE")) {
updateSpace(code, view.getViewcell(), cview.getViewcell());
}
}
};
}

View File

@@ -0,0 +1,71 @@
/*
SplitNileView.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.module;
import org.gzigzag.*;
import java.awt.*;
/** A view that shows two Nile streams side-by-side. */
public class SplitNileView implements FlobView, ZOb {
public static final String rcsid = "$Id: SplitNileView.zob,v 1.1 2000/12/26 20: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 {
/** The space to leave between the two Nile streams. */
int margin
= 20;
}
public void raster(FlobSet into, FlobFactory fact,
ZZCell win, String[] dims, ZZCell accursed) {
ZZCell leftc = accursed.s("d.nile-pair", -1);
ZZCell rightc = accursed.s("d.nile-pair");
if(leftc != null && rightc == null)
rightc = accursed;
else if(leftc == null && rightc != null)
leftc = accursed;
else
throw new ZZError("HELP! Strange d.nile-pair arrangement XXX");
ZZCell leftacc = ZZCursorReal.get(leftc);
ZZCell rightacc = ZZCursorReal.get(rightc);
Dimension size = new Dimension(into.getSize());
size.width = (size.width - margin) / 2;
FlobSet left = into.create(size), right = into.create(size);
Nile1View view = new Nile1View();
view.init__zob();
SimpleBeamer bmr = new SimpleBeamer();
view.raster(left, fact, leftc, dims, leftacc);
view.raster(right, fact, rightc, dims, rightacc);
into.fetch(left, 0, 0, 0);
into.fetch(right, size.width + margin, 0, 0);
bmr.decorate(into, "", null);
}
}

View File

@@ -0,0 +1,166 @@
/*
Nile3Ops.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.module;
import org.gzigzag.*;
import java.util.*;
/** A library of routines for operating on Nile streams.
* @see Nile1
*/
public abstract class Nile3Ops {
public static final String rcsid = "$Id: Nile3Ops.java,v 1.1 2001/01/07 18:59:06 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); }
static public void saveCursor(ZZCell win) {
ZZCell s = win.getOrNewCell("d.nile-save", 1);
if(ZZCursorReal.get(s) == null)
ZZCursorReal.set(s, new ZZCursorReal(win));
}
static public void clearSavedCursor(ZZCell win) {
ZZCell s = win.getOrNewCell("d.nile-save", 1);
if(ZZCursorReal.get(s) != null)
ZZCursorReal.set(s, (ZZCell)null);
}
static public ZZCursor getSavedCursor(ZZCell win) {
ZZCell s = win.getOrNewCell("d.nile-save", 1);
return new ZZCursorReal(s);
}
static public void setCursor(Nile3Unit unit, ZZCell win, ZZCursor to) {
Nile3Pos pos = new Nile3Pos(to);
setPart(win, unit.extend(pos));
}
static public void moveCursor(Nile3Unit unit, ZZCell win, int dir) {
Nile3Part part = getPart(win);
if(!unit.step(part, dir)) return;
setPart(win, part);
}
static public void adjust(Nile3Unit unit, ZZCell win, int end, int dir) {
Nile3Part part = getPart(win);
if(!unit.adjust(part, end, dir)) return;
setPart(win, part);
}
static public void hop(Nile3Unit unit, ZZCell win, int dir) {
Nile3Part part = getPart(win);
Nile3Pos pos = part.side(dir);
if(!unit.insertPos(pos, dir, part, false)) return;
unit.move(part, pos, false);
setPart(win, part);
}
/** Tunnel text from one nile window to another.
* The text can be copied or cut.
*/
static public void tunnel(Nile3Unit unit, ZZCell from, ZZCell to,
boolean copy) {
Nile3Part part = getPart(from);
Nile3Pos pos = getPart(to).start;
if(!unit.insertPos(pos, -1, part, true)) return;
unit.move(part, pos, copy);
setPart(to, part);
}
static public boolean insert(ZZCell win, String key) {
if(key == null)
return false;
if(key.length() != 1)
return false;
Nile3Pos pos = getPart(win).start;
pos.insert(key, 1);
setPos(win, pos);
return true;
}
static public void backspace(Nile3Unit unit, ZZCell win) {
Nile3Part orig = getPart(win);
Nile3Part part = new Nile3Part(orig.start, orig.start);
unit.edge(part.start, -1, -1, false);
unit.edge(part.end, 1, -1, true);
unit.cut(part);
}
static public void del(Nile3Unit unit, ZZCell win) {
Nile3Pos pos = unit.cut(getPart(win));
setPos(win, pos);
}
static public void breakParagraph(Nile3Unit unit, ZZCell win) {
Nile3Part part = getPart(win);
part.start.breakParagraph();
}
/** Get a whole Nile stream as a string, properly capitalized.
* Converts paragraph breaks (==struct cells) to double newlines.<br>
* XXX a) It's no good this calls Nile1View.<br>
* XXX b) Do this for a Nile3Part (a selection), not only
* for a whole stream.<br>
* XXX c) Does this belong in this class? (It seemed to fit?)
*
* @param inStream Some cell inside the stream to be read.
*/
static public String stringify(ZZCell inStream) {
ZZCell hd = inStream.h("d.nile");
Nile1View n1v = new Nile1View();
n1v.init__zob();
String s = "";
ZZCell tail = Nile2Iter.findStruct(hd, 1, false);
while(hd != null) {
FText ft = n1v.paragraph(hd, tail, null, null, null);
ft.capitalize();
s = s + FText.Part.join(ft.parts);
hd = tail;
if(hd != null) tail = Nile2Iter.findStruct(hd, 1, false);
s = s + "\n\n";
}
return s;
}
// Shorthand...
static public Nile3Part getPart(ZZCell win) {
ZZCursorReal start = new ZZCursorReal(win);
if(start.getOffs() == start.NO_OFFSET)
start = new ZZCursorReal(win.getOrNewCell("d.nile-save"));
ZZCursorReal end = new ZZCursorReal(win.getOrNewCell("d.nile-sel"));
return new Nile3Part(start, end);
}
static public void setPart(ZZCell win, Nile3Part part) {
ZZCursor start = part.start.get(), end = part.end.get();
ZZCursorReal.set(win, start.get());
// if(ZZCursorReal.getOffs(win) != ZZCursorReal.NO_OFFSET)
ZZCursorReal.setOffs(win, start.getOffs());
ZZCursorReal.set(win.getOrNewCell("d.nile-save"), start);
ZZCursorReal.set(win.getOrNewCell("d.nile-sel"), end);
}
static public void setPos(ZZCell win, Nile3Pos pos) {
setPart(win, new Nile3Part(pos, pos));
}
}

View File

@@ -0,0 +1,132 @@
/*
Nile3Part.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.*;
/** A Nile span, with a start and an end.
* This object explicitly assumes no modifications to the
* stream while it is working.
*/
public final class Nile3Part implements Cloneable {
public static final String rcsid = "$Id: Nile3Part.java,v 1.1 2001/01/07 18:59:06 bfallenstein Exp $";
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); }
public final Nile3Pos start = new Nile3Pos();
public final Nile3Pos end = new Nile3Pos();
public Nile3Part(Nile3Pos start, Nile3Pos end) {
this.start.set(start); this.end.set(end);
check();
}
public Nile3Part(ZZCursor start, ZZCursor end) {
p(start + " " + end);
this.start.set(start); this.end.set(end);
check();
}
public Nile3Pos side(int dir) {
if(dir < 0) return start;
else return end;
}
public Nile3Pos cut() {
if(isStream())
return null; // XXX should this throw an error?
check();
start.split(false, 1);
end.split(false, -1);
Nile3Pos before = (Nile3Pos)start.clone();
Nile3Pos after = (Nile3Pos)end.clone();
if(!before.bias(-1) || !after.bias(1))
throw new ZZError("HELP! End of stream after split! XXX");
start.c.disconnect("d.nile", -1);
end.c.disconnect("d.nile", 1);
before.c.connect("d.nile", 1, after.c);
return before;
}
/** Make a cell's content into a span. */
static public Span spanify(ZZCell c0) {
Span sp = c0.getSpan();
if(sp != null) return sp;
StringScroll sc = c0.getSpace().getStringScroll();
String s = c0.getText();
long soffs = sc.append(s);
sp = Span.create(
Address.scrollOffs(sc, soffs),
Address.scrollOffs(sc, soffs + s.length() - 1)
);
c0.setSpan(sp);
return sp;
}
public Nile3Part copy() {
check();
start.split(false, 1);
end.split(false, -1);
ZZCell c = start.c;
ZZCell first = c.N(), last = first;
while(true) {
last.setSpan(spanify(c));
if(c.equals(end.c)) break;
c = c.s("d.nile");
last = last.N("d.nile");
}
return new Nile3Part(
new ZZCursorVirtual(first, 0),
new ZZCursorVirtual(last, last.getText().length()));
}
/** Return true if there's nothing before or after this. */
public boolean isStream() {
return start.end(-1) && end.end(1);
}
/** Check the integrity of this Nile3Part: start &lt;= end? */
public void check() {
boolean good = true;
if(start.c.equals(end.c)) {
good = start.offs <= end.offs;
p(start.offs + " " + end.offs);
} else {
good = start.c.findCell("d.nile", 1, end.c);
p(start.c + " " + end.c);
}
if(!good)
throw new ZZError("Malformed Nile3Part stream! XXX");
}
public Object clone() {
try {
return super.clone();
} catch(CloneNotSupportedException e) {
ZZLogger.exc(e);
return null;
}
}
}

View File

@@ -0,0 +1,338 @@
/*
Nile3Pos.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.util.*;
/** A character-level iterator object that knows about
* paragraphs for a Nile stream.
* This object explicitly assumes no modifications to the
* stream while it is working.
* The position is between the characters, not on a character.
* Actually, it is <em>between (a char | a para boundary) and
* (a char | a para boundary)</em>, i.e., it can be at the beginning or end
* of a para or between two paras.
*/
public final class Nile3Pos implements Cloneable {
public static final String rcsid = "$Id: Nile3Pos.java,v 1.1 2001/01/07 18:59:06 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); }
/** Returned by type() or read(), this denotes end/beginning of stream. */
public static final int END = -1;
/** Returned by type() or read(), this denotes a paragraph break. */
public static final int PARA = -2;
/** Returned by type(), this means punctuation. */
public static final int PUNCT = -3;
/** Returned by type(), this means alphanumeric character. */
public static final int ALPHA = -4;
/** Returned by type(), this means whitespace. */
public static final int WS = -5;
/** Returned by read(), this means special thing (to type, it's PUNCT). */
public static final int SPECIAL = -6;
ZZCell c;
int offs;
// Cache these for speed.
// Note: ctxt and cspan are only valid if NOT (isStruct || isSpecial)!
int clen;
String ctxt;
Span cspan;
// Is this cell a struct cell, a text object?
private boolean isStruct, isSpecial;
public Nile3Pos(Nile3Pos pos) { set(pos); }
public Nile3Pos(ZZCursor pos) { set(pos); }
Nile3Pos() {}
public ZZCursor get() { return new ZZCursorVirtual(c, offs); };
private void load(ZZCell c) {
this.c = c;
isStruct = (c.s("d.nile-struct", 1) != null);
isSpecial = (c.s("d.nile-special", 1) != null);
if(isStruct || isSpecial)
clen = 1;
else {
ctxt = c.getText();
cspan = c.getSpan();
clen = ctxt.length();
}
}
public void set(Nile3Pos pos) {
load(pos.c);
offs = pos.offs;
}
public void set(ZZCursor pos) {
load(pos.get());
offs = pos.getOffs();
if(offs == pos.NO_OFFSET) offs = 0;
}
/** Internal convenience: try to insert with bias, if can't, return */
private boolean insert(String s, int side, int bias) {
if(!bias(bias)) return false;
if(cspan != null) return false;
c.setText(ctxt.substring(0, offs) + s + ctxt.substring(offs));
ZZCursorReal.adjustCursors(c, offs, s.length());
if(side > 0) offs += s.length();
return true;
}
public void insert(String s, int side) {
if(insert(s, side, 1)) return;
if(offs == 0)
if(insert(s, side, -1)) return;
split(false, 1);
load(c.N("d.nile", -1));
c.setText(s);
offs = (side < 0) ? (0) : (clen);
}
public void insert(Nile3Part what, int side) {
if(!what.isStream())
throw new ZZError("Can't insert non-stream Nile3Part!");
split(false, side);
ZZCell other = c.s("d.nile", -side);
c.disconnect("d.nile", -side);
c.connect("d.nile", -side, what.side(side).c);
other.connect("d.nile", side, what.side(-side).c);
}
public boolean delete(int bias) {
// First, ensure we are in the same cell as the character to delete.
if(!bias(bias)) return false;
// Then, a special case check (also for isStruct and isSpecial cells)
if(clen == 1) {
ZZCell from = c;
if(c.s("d.nile") != null) {
load(c.s("d.nile"));
offs = 0;
} else if(c.s("d.nile", -1) != null) {
load(c.s("d.nile", -1));
offs = clen;
} else {
load(c.N("d.nile"));
offs = 0;
}
Enumeration e = ZZCursorReal.getPointers(from);
while(e.hasMoreElements()) {
ZZCell curs = (ZZCell)e.nextElement();
ZZCursorReal.setcursor(curs, c);
if(ZZCursorReal.getOffs(curs) != ZZCursorReal.NO_OFFSET)
ZZCursorReal.setOffs(curs, offs);
}
from.delete();
return true;
}
if(cspan == null) {
if(bias < 0) offs--;
c.setText(ctxt.substring(0, offs) + ctxt.substring(offs));
ZZCursorReal.adjustCursors(c, offs, -1);
} else {
split(false, bias);
if(bias > 0) c.setSpan(cspan.subSpan(1));
else c.setSpan(cspan.subSpan(0, clen-1));
}
load(c);
return true;
}
/** Split at the current position.
* The original cell will remain the first.
* If side is greater than zero, this pos will be set to the second cell;
* if side is less than zero, this pos will be set to the first cell.
* If offs is zero or equal to the number of characters in c, nothing is
* done and either the current cell or the next cell is returned.
* <p>
* The most special case involves doing this at the very end of the stream,
* in which case an empty new cell is created and returned.
* @param side The side of the split to make this Nile3Pos point to.
* @param always Whether to split even if the offset is at the beginning
* or end of a cell. Used e.g. for inserting a paragraph.
*/
public void split(boolean always, int side) {
if(always) {
ZZCell c1 = c.N("d.nile");
if(cspan == null) {
c.setText(ctxt.substring(0, offs));
c1.setText(ctxt.substring(offs));
} else {
c.setSpan(cspan.subSpan(0, offs));
c1.setSpan(cspan.subSpan(offs));
}
Enumeration e = ZZCursorReal.getPointers(c);
while(e.hasMoreElements()) {
ZZCell p = (ZZCell)e.nextElement();
int poffs = ZZCursorReal.getOffs(p);
if(poffs != ZZCursorReal.NO_OFFSET && poffs > offs) {
ZZCursorReal.setcursor(p, c1);
ZZCursorReal.setOffs(p, poffs-offs);
}
}
if(side > 0) { load(c1); offs = 0; }
} else {
if(offs == 0) {
if(side < 0) {
load(c.getOrNewCell("d.nile", -1));
offs = clen;
}
} else if(offs >= clen) {
if(side > 0) {
load(c.getOrNewCell("d.nile"));
offs = 0;
}
} else
split(true, side);
}
}
public int type(int dir) {
int ch = read(dir);
if(ch < 0) return ch;
if(Character.isLetterOrDigit((char)ch)) return ALPHA;
if(Character.isWhitespace((char)ch)) return WS;
return PUNCT;
}
/** Return true if type() would return <code>Nile3Pos.END</code>. */
public boolean end(int dir) {
return type(dir) == END;
}
/** Return true if type() would return <code>Nile3Pos.PARA</code>. */
public boolean para(int dir) {
return type(dir) == PARA;
}
/** Return true if type() would return <code>Nile3Pos.PUNCT</code>. */
public boolean punct(int dir) {
return type(dir) == PUNCT;
}
/** Return true if type() would return <code>Nile3Pos.ALPHA</code>. */
public boolean alpha(int dir) {
return type(dir) == ALPHA;
}
/** Return true if type() would return <code>Nile3Pos.WS</code>. */
public boolean ws(int dir) {
return type(dir) == WS;
}
/** Return true if boundary, i.e. if end() or para() would return true. */
public boolean boundary(int dir) {
int t = type(dir);
return (t == END) || (t == PARA);
}
/** Return true if boundary() or ws() would test true. */
public boolean bws(int dir) {
int t = type(dir);
return (t == WS) || (t == END) || (t == PARA);
}
/** Read character in given direction. */
public int read(int dir) {
if(!bias(dir)) return END;
if(isStruct) return PARA;
if(isSpecial) return SPECIAL;
return ctxt.charAt((dir < 0) ? (offs - 1) : (offs));
}
/** Move n characters forwards or backwards.
* If the offset given is out of bounds, moves as far as possible
* and returns false, otherwise returns true. In general, this moves as
* little as possible, i.e. if n was positive, bias is negative, and if
* n was negative, bias is positive after call.
*/
public boolean move(int n) {
n += offs;
offs = 0;
while(n > clen) {
n -= clen;
ZZCell nc = c.s("d.nile");
if(nc == null) {
// End of stream!
offs = clen;
if(n > 0) return false;
return true;
}
load(nc);
}
while(n < 0) {
ZZCell nc = c.s("d.nile", -1);
if(nc == null) {
offs = 0;
return false;
}
load(nc);
n += clen;
}
offs = n;
return true;
}
/** (Convenience:) Move if doMove is true.
* This is used by Nile3Unit to make includeThis code simpler.
*/
public boolean move(boolean doMove, int n) {
if(doMove) return move(n);
else return true;
}
/** Ensure bias in a given direction.
* This means that after bias(1), we are in the cell that contains the
* character in positive direction, and after bias(-1), same in negative
* direction.<br>
* If we bump on the end of the stream, return false, else return true.
*/
boolean bias(int dir) {
if(offs + dir >= 0 && offs + dir <= clen) return true;
do {
ZZCell nc = c.s("d.nile", dir);
if(nc == null) return false;
load(nc);
} while(clen == 0);
return true;
}
public void breakParagraph() {
split(false, 1);
c.N("d.nile", -1).N("d.nile-struct").setText("P");
}
public Object clone() {
try {
return super.clone();
} catch(CloneNotSupportedException e) {
ZZLogger.exc(e);
return null;
}
}
}

View File

@@ -0,0 +1,305 @@
/*
Nile3Unit.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, based on Nile2Unit by Tuomas Lukka
*/
package org.gzigzag.module;
import org.gzigzag.*;
/** A nile unit of division.
* Spaces between units may be non-zero-width. Units may be zero-width, if
* neighbouring units are separated by non-zero spaces.
*/
public abstract class Nile3Unit {
public static final String rcsid = "$Id: Nile3Unit.java,v 1.1 2001/01/07 18:59:06 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 static class Char extends Nile3Unit {
public boolean isEdge(Nile3Pos pos, int dir) {
return !pos.boundary(dir);
}
}
public static class Word extends Nile3Unit {
/** An alphanumeric word. */
static final int AWORD = 1;
/** A punctuation word, e.g. a smilie. */
static final int PWORD = 2;
/** An A- or PWORD. */
static final int WORD = AWORD | PWORD;
/** A piece of left-bound punctuation, like commas. */
static final int LPUNCT = 4;
/** A piece of right-bound punctuation, like opening brackets. */
static final int RPUNCT = 8;
/** A piece of left- or right-bound punctuation. */
static final int BPUNCT = LPUNCT | RPUNCT;
/** A paragraph boundary or the end of the stream. */
static final int BOUNDARY = 16;
/** Not a correct combination of words. */
static final int BAD = 0;
/** Correct combination iff no space in between. */
static final int NSP = 1;
/** Correct combination iff space in between. */
static final int SP = 2;
/** The type of a joining position. */
public static final int jointype(int lefttype, int righttype) {
if(lefttype & WORD > 0 && righttype & WORD > 0)
return SP;
else if(lefttype == AWORD && righttype == LPUNCT)
return NSP;
else if(lefttype == AWORD && righttype == RPUNCT)
return SP;
else if(lefttype == RPUNCT && righttype == AWORD)
return NSP;
else if(lefttype == LPUNCT && righttype == AWORD)
return SP;
else if(lefttype & BPUNCT > 0 && righttype == lefttype)
return NSP;
else if(lefttype == LPUNCT && righttype == RPUNCT)
return SP;
else if(lefttype == BOUNDARY && righttype == BOUNDARY)
return NSP;
else if(lefttype == BOUNDARY && righttype & WORD > 0)
return NSP;
else if(lefttype & WORD > 0 && righttype == BOUNDARY)
return NSP;
else if(lefttype == LPUNCT && righttype == BOUNDARY)
return NSP;
else if(lefttype == BOUNDARY && righttype == RPUNCT)
return NSP;
else
return BAD;
}
/** Find out the types of the words next to a word boundary.
* This may only be called on what is known to be a word boundary.
* Else, its behavior is undefined.
*/
public static final int[] wordtype(Nile3Pos pos, int dir) {
int[] res = new int[2];
int lch = pos.type(-1), rch = pos.type(1);
boolean lp = pos.punct(-1), rp = pos.punct(1);
Nile3Pos lpos, rpos;
if(lp) {
lpos = (Nile3Pos)pos.clone();
while(lpos.punct(-1)) lpos.move(-1);
}
if(rp) {
rpos = (Nile3Pos)pos.clone();
while(rpos.punct(1)) rpos.move(1);
}
if(!lp && !rp) {
if(pos.
}
public void cleanJoin(Nile3Pos pos, int lefttype, int righttype) {
int type = jointype(lefttype, righttype);
if(jointype == NSP) {
while(pos.ws(-1)) pos.delete(-1);
while(pos.ws(1)) pos.delete(1);
} else if(jointype == SP) {
if(!pos.ws(-1) && !pos.ws(1)) pos.insert(" ", 1);
} else {
p("Nile3Unit.Word: Detected bad joining in cleanJoin");
}
}
public boolean isEdge(Nile3Pos pos, int dir) {
if(pos.punct(-dir)) return true;
if(pos.bws(dir) && pos.alpha(-dir)) return true;
return false;
}
/** Can what be inserted at pos? */
public boolean isInsertPos(Nile3Pos pos, Nile3Part what) {
if(!pos.boundary(1) && !isEdge(pos, -1)) return false;
if(what.start.punct(1) && !what.start.bws(-1)) {
}
if(what.end.punct(-1) && !what.end.bws(1)) {
if(
}
if(jointype(pos.-1, what.start.1) == BAD) return false;
if(jointype(pos.1, what.end.-1) == BAD) return false;
}
}
public static class Sentence extends Nile3Unit {
public boolean isEdge(Nile3Pos pos, int dir) {
if(pos.ws(dir)) return false;
if(pos.boundary(-dir)) return true;
if(!pos.move(-dir)) return false;
if((pos.bws(-dir)) && pos.ws(dir)) return true;
pos.move(dir);
return false;
}
}
// Ugh! Paragraph is *inefficient*!
// XXX is this a problem? in very long paragraphs maybe?
public static class Paragraph extends Nile3Unit {
public boolean isEdge(Nile3Pos pos, int dir) {
return pos.boundary(-dir);
}
}
public boolean step(Nile3Part part, int n) {
int abs = (n < 0) ? (-n) : (n);
int dir = (n < 0) ? (-1) : (1);
Nile3Pos pos = part.side(dir), other = part.side(-dir);
for(int i=0; i<abs; i++) {
other.set(pos);
if(!edge(other, -dir, dir, true)) return false;
pos.set(other);
if(!edge(pos, dir, dir, false)) return false;
}
return true;
}
public boolean adjust(Nile3Part part, int side, int n) {
int abs = (n < 0) ? (-n) : (n);
int dir = (n < 0) ? (-1) : (1);
for(int i=0; i<abs; i++) {
if(!edge(part.side(side), side, dir, false)) return false;
}
return true;
}
public Nile3Part extend(Nile3Pos pos) {
Nile3Part res = new Nile3Part(pos, pos);
if(!extend(res)) return null;
return res;
}
public boolean extend(Nile3Part part) {
if(!edge(part.start, -1, -1, true)) return false;
if(!edge(part.end, 1, 1, true)) return false;
return true;
}
public boolean delete(Nile3Part part) {
cleanUp(part.delete());
}
protected void cleanUp(Nile3Pos pos) {}
/** Move a Nile3Part to a position. */
public void move(Nile3Part what, Nile3Pos where, int moveDir,
boolean includeThis, boolean copy) {
// First, prepare the part.
if(!extend(what)) return null;
if(copy) what = what.copy();
else rmSpace(what.cut());
// Then, prepare the pos.
if(!insertPos(pos, moveDir, what, includeThis)) return null;
// Finally, move.
Nile3Pos res = paste(what, where);
rmSpace(res);
return res;
}
/** The previous or next position where this type of unit may be inserted.
* By standard, return edge(pos, -1, dir, includeThis).
*/
protected boolean insertPos(Nile3Pos pos, int dir, Nile3Part what,
boolean includeThis) {
if(!pos.move(!includeThis, moveDir)) return false;
do {
if(pos.boundary(1) || isEdge(pos, -1)) return true;
} while(pos.move(moveDir));
return false;
}
/** Is this an edge of this type of unit in the given direction?
* Positive direction means there follows such a unit after this point;
* negative direction menas this point is preceded by such a unit.
*/
protected abstract boolean isEdge(Nile3Pos pos, int dir);
public boolean edge(Nile3Pos pos, int edgeDir, int moveDir,
boolean includeThis) {
if(!pos.move(!includeThis, moveDir)) return false;
do {
if(isEdge(pos, edgeDir)) return true;
} while(pos.move(moveDir));
return false;
}
/** The previous or next beginning position of this type of unit.
* @returns false if we bump into end of string.
*/
public boolean start(Nile3Pos pos, int dir, boolean includeThis) {
return edge(pos, -1, dir, includeThis);
}
/** The previous or next ending position of this type of unit.
* @returns false if we bump into end of string.
*/
public boolean end(Nile3Pos pos, int dir, boolean includeThis) {
return edge(pos, 1, dir, includeThis);
}
/** Modify the selection so that it makes sense to the user. */
public boolean select(Nile3Part part, boolean extend) {
boolean res = start(part.start, extend ? -1 : 1, true);
res = res && end(part.end, extend ? 1 : -1, true);
return res;
}
/** Modify the selection for moving it around (cut, copy) */
public boolean prepare(Nile3Part part) {
return true;
}
/** Cut the stream.
* This routine modifies the Nile3Part to point
* to the cut stream, and returns the cut position.
* @return The pasted-together cutaway point, from which
* the insert position can be searched with !includeThis.
*/
public Nile3Pos cut(Nile3Part part) { return part.cut(); }
/** Copy a part of the stream.
* First every cell is spanified, then a new stream with the same spans
* is created.
* This routine modifies the start and to iterators to point
* to the beginning and end of the copied stream.
* XXX any special copying rules to obey, like in cut?
*/
public Nile3Part copy(Nile3Part what) {
this.start(what.start, -1, true);
this.end(what.end, 1, true);
return what.copy();
}
protected void paste(Nile3Pos at, Nile3Part what) { at.insert(what, 1); }
}

212
Modules/notemap/Notemap.zob Normal file
View File

@@ -0,0 +1,212 @@
/*
Notemap.zob
*
* Copyright (c) 2000-2001 Ted Nelson and Tuomas Lukka
* Copyright (c) 2000-2001 Benjamin 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 Benjamin Fallenstein
*/
package org.gzigzag.module;
import org.gzigzag.*;
import java.util.*;
import java.awt.*;
/** The Map view
*/
public class Notemap implements FlobView, ZOb {
public static final String rcsid = "$Id: Notemap.zob,v 1.3 2001/01/06 21:32:18 bfallenstein Exp $";
public static boolean dbg = true;
static void p(String s) { if(dbg) System.out.println(s); }
static void pa(String s) { System.out.println(s); }
STRUCTPARAMS {
/** The maximum depth */
int maxdepth
= 2;
}
static public String dim1 = "d.map-1", dim2 = "d.map-2";
/** A typed link between two cells. */
static public class Link {
/** The direction of the link. May be 0, in case of no direction. */
int dir;
ZZCell link, to, linkRoot;
Color col = Color.blue;
/** Constructor sets dir to zero if there is no direction. */
public Link(ZZCell link, int dir, ZZCell to) {
this.link = link; this.to = to;
// linkRoot = link.getRootclone();
// if(linkRoot.s("d.map-directed") != null)
this.dir = dir;
// else
// dir = 0;
}
}
/** Get the links from a given cell. */
static public Link[] getLinks(ZZCell from, ZZCell fromLink,
boolean[] tilt) {
Vector v = new Vector();
ZZCell c, d;
int offs = -1;
for(c = from.s(dim2); c != null && !c.equals(from); c = c.s(dim2)) {
d = c.h(dim1, -1, true);
if(d != null) {
if(!c.equals(fromLink))
v.addElement(new Link(c, -1, d));
else
offs = v.size();
} else
ZZLogger.log("link without neg target: "+c);
}
tilt[0] = (fromLink == null) && (v.size() % 2 == 1);
int negmiddle = v.size() / 2;
for(c = from.s(dim1); c != null && !c.equals(from); c = c.s(dim1)) {
d = c.h(dim2, -1, true);
if(d != null) {
if(!c.equals(fromLink))
v.addElement(new Link(c, 1, d));
else
offs = v.size();
} else
ZZLogger.log("link without pos target: "+c);
}
if(fromLink == null) offs = negmiddle;
else if(offs < 0) throw new ZZError("fromLink not found");
Link[] res = new Link[v.size()];
if(offs == res.length) offs = 0; // end of array = beginning of array
for(int i=offs; i<res.length; i++)
res[i-offs] = (Link)v.elementAt(i);
for(int i=0; i<offs; i++)
res[i+res.length-offs] = (Link)v.elementAt(i);
return res;
}
public void part(FlobSet into, FlobFactory fact,
ZZCell from, ZZCell fromLink, int x0, int y0, int dpt,
int lx, int ly, double arcs, double arce, int xd, int yd,
boolean firstRound) {
boolean tilt[] = new boolean[1];
Link[] links = getLinks(from, fromLink, tilt);
p("part dpt "+dpt+" arcs/pi "+arcs/Math.PI+" arce/pi "+arce/Math.PI+" from "+from+" exc "+fromLink);
int count = links.length;
// if(firstRound && count == 1) {
// double arcq = (arce - arcs) / 4;
// arcs += arcq; arce -= arcq;
// } else if(firstRound && count == 2) {
// arcs += Math.PI / 2;
// }
double arcd = (arce-arcs) / count;
double arcdh = arcd / 2;
Point p = new Point();
LineDecor.Builder lb = new LineDecor.Builder(into, Color.black);
lb.startl(count*4, 2);
ArrowDecor.Builder ab = new ArrowDecor.Builder(into, Color.blue);
ab.startl(count*4, 2);
double arc = arcs;
if(firstRound && tilt[0]) arc -= arcdh;
for(int i=0; i<count; i++, arc += arcd) {
p.x = x0 + (int)Math.round(Math.sin(arc+arcdh)*xd*dpt);
p.y = y0 + (int)Math.round(Math.cos(arc+arcdh)*yd*dpt);
int dx = p.x - lx, dy = p.y - ly, mx = lx + dx/2, my = ly + dy/2;
int ax, ay; // Half the size of the arrow
if(dx == 0) { ax = 0; ay = dy > 0 ? 10 : -10; }
else if(dy == 0) { ax = dx > 0 ? 10 : -10; ay = 0; }
else {
double raise = dy / (double)dx;
ax = (int)Math.sqrt(100/(raise*raise+1));
if(dx < 0) ax = -ax;
ay = (int)(raise*ax);
}
fact.centerFlob(into, links[i].to, links[i].to, 1, p, 0, 0, 1);
lb.l(lx, ly, p.x, p.y);
if(links[i].dir < 0)
ab.ar(mx+ax, my+ay, mx-ax, my-ay);
else if(links[i].dir > 0)
ab.ar(mx-ax, my-ay, mx+ax, my+ay);
if(dpt < maxdepth)
part(into, fact, links[i].to, links[i].link, x0, y0, dpt+1,
p.x, p.y, arc, arc+arcd, xd, yd, false);
}
lb.endl();
ab.endl();
}
public void raster(FlobSet into, FlobFactory fact,
ZZCell view, String[] dims, ZZCell accursed) {
Dimension size = into.getSize();
int x0 = size.width/2, xd = size.width / (2 * maxdepth);
int y0 = size.height/2, yd = size.height / (2 * maxdepth);
fact.centerFlob(into, accursed, accursed, 1,
new Point(x0, y0), 0, 0, 1);
part(into, fact, accursed, null, x0, y0, 1, x0, y0,
-Math.PI/2, (Math.PI/2)*3, xd, yd, true);
}
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) {
if(id.equals("NEW")) {
ZZCell vc = view.getViewcell();
ZZCell c = ZZCursorReal.get(vc).N(dim1).N(dim2, -1);
ZZCursorReal.set(vc, c);
} else if(id.equals("CNCT")) {
ZZCell vc = view.getViewcell();
ZZCell acc = ZZCursorReal.get(vc);
ZZCell[] marks = vc.readRank("d.mark", 1, false);
for(int i=0; i<marks.length; i++) {
ZZCell m = marks[i];
ZZCell to = m.h("d.mark-set");
m.excise("d.mark"); m.excise("d.mark-set");
acc.insert(dim1, 1, m);
to.insert(dim2, 1, m);
}
} else {
pa("Unknown Map module action: "+id);
}
}
public ZOb newZOb(String id) {
if(id.equals("Star"))
return new Notemap();
else
return null;
}
};
}

22
Modules/openGL/Makefile Normal file
View File

@@ -0,0 +1,22 @@
# IBMCFLAGS=-Dint64_t="long long" -Dlinux -g
IBMCFLAGS=-Dlinux -g
JAVAC=javac
CC=g++
#CC=/usr/bin/gcc
OFLAGS= -Wall # -O2 -ffast-math -fexpensive-optimizations
INCLUDES= -I/usr/local/java/include -I/usr/local/java/include/linux -I/usr/X11R6/include
LIBS= -L/usr/X11R6/lib -lm -lGL -lGLU -lglut -lX11 -lXext -lXmu -lXt -lXi\
-lSM -lICE -lgltt
# -lSM -lICE -liconv -lgltt
lib:
$(CC) $(IBMCFLAGS) -shared ZZOpenGLGraphics.cc $(INCLUDES) $(LIBS) \
-o libzz3d.so $(OFLAGS)
java:
$(JAVAC) *.java
clean:
-rm *.o *~ *.class javacore.txt
old:
$(CC) -shared Scene_Xlib.cc $(INCLUDES) $(LIBS) \
-o libzz3d.so $(OFLAGS)

View File

@@ -0,0 +1,133 @@
/*
OpenGLCloud.java
*
* Copyright (c) 2000, Ted Nelson, Tuomas Lukka and Vesa Parkkinen
*
* 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 Vesa Parkkinen
*/
package org.gzigzag.module;
import org.gzigzag.*;
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
/**
* A Simple OpenGL test.
*/
public class OpenGLCloud {
public static final String rcsid = "$Id: OpenGLCloud.java,v 1.4 2000/10/18 14:35:32 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); }
OpenGLCloud(){
}
static public ZZModule module = new ZZModule() {
ZZOpenGLGraphics o;
int xk = -20;
public void action(String id,
ZZCell code,
ZZCell target,
ZZView view, ZZView cview,
String key, Point pt, ZZScene xi) {
ZZCell viewCell = view.getViewcell();
ZZCell viewCursor = ZZCursorReal.get(viewCell);
Object ob = null;
if(pt != null && xi != null)
ob = xi.getObjectAt(pt.x, pt.y);
p("openGL action! '"+id+"' key: "+key);
if(id.equals("TEST")) {
} else if(id.equals("OPENWIN")) {
p("openGL OPENWIN");
o = new ZZOpenGLGraphics();
o.openWindow(400,400);
o.addKeyListener(new KeyListener(){
public void keyTyped(KeyEvent e){
p("****KEY TYPED: " + e);
}
public void keyPressed(KeyEvent e){
p("****KEY PRESSED: " + e);
key( e.getKeyChar() );
}
public void keyReleased(KeyEvent e){
p("****KEY RELEASED: " + e);
}
});
o.putLine(20,20,30,10, "TEST");
o.putText( "Just testing",-20,30);
o.putText( "Another String...",-20,20);
o.putText( "Line ",-20,10);
o.putText( "Last line",-20,0);
o.putArrow(-10, -10, 10,10,new Color(1,0,0),"TEST");
/*
ZZCell c = target;
for( int i = 0; i < 5 ; i++){
o.putCell(c, 0,0 - i*10,25,8,"TEST");
c = c.s("d.2", 1);
if ( c != null ){
o.putLine(12,0-i*10,12,50 - i*10 - 2, "TEST");
}else
break;
}
c = target.s("d.2", -1);;
if( c != null )
for( int i = 1; i < 5 ; i++){
o.putCell(c, 0, i*10,25,8,"TEST");
c = c.s("d.2", -1);
if ( c != null ){
o.putLine(12,i*10+10,12, i*10 + 2, "TEST");
}else
break;
}
*/
o.start();
}
}
public void key(char k){
p("===KEY===");
xk += 10;
o.putText( "" + k ,xk ,-20);
}
public ZZRaster getRaster(String id){
return null;
}
};
}

View File

@@ -0,0 +1,474 @@
/****************************************************
* INCLUDES
****************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
// #include <iconv.h>
#include <math.h>
extern "C"{
#include "jni.h"
}
#include "fi_iki_lukka_ZZOpenGLGraphics.h"
#include "gltt/FTEngine.h"
#include "gltt/FTFace.h"
#include "gltt/FTInstance.h"
#include "gltt/FTGlyph.h"
#include "gltt/FTGlyphBitmap.h"
#include "gltt/FTGlyphPixmap.h"
#include "gltt/FTBitmapFont.h"
#include "gltt/GLTTBitmapFont.h"
#include "gltt/GLTTPixmapFont.h"
#include "gltt/GLTTOutlineFont.h"
#include "gltt/GLTTFont.h"
#include "gltt/GLTTGlyphPolygonizer.h"
#include "gltt/GLTTGlyphTriangulator.h"
#include <GL/glx.h>
#include <GL/glu.h>
#include <GL/glut.h>
#include <X11/Xatom.h>
#include <X11/Xmu/StdCmap.h>
#include <X11/keysym.h>
/***********************************************
* useful little macros
************************************************/
#define GET_THIS() jclass zzthis = env->GetObjectClass( obj );
#define FIELD_ID(_name, _sig) env->GetFieldID( zzthis, _name, _sig)
#define SET_INT_FIELD(_name, _value) \
env->SetIntField( obj, FIELD_ID(_name, "I"), _value)
#define GET_INT_FIELD(_name) env->GetIntField( obj, FIELD_ID(_name, "I"))
/******************************************************
* GLOBALS
******************************************************/
/* these will be in java class */
Display *disp;
Window win;
/***/
GLboolean db = GL_TRUE; /* doublebuffering */
GLint disp_list = 0;
XSizeHints sizeHints = { 0 };
XEvent event;
GLuint base;
int args[] = { GLX_DOUBLEBUFFER,
GLX_RGBA,
GLX_DEPTH_SIZE,
16,
None };
void makeRasterFont(Display *dpy)
{
XFontStruct *fontInfo;
Font id;
unsigned int first, last;
fontInfo = XLoadQueryFont(dpy,
"-*-courier-medium-r-normal-*-*-100-*-*-m-*-iso8859-1");
if (fontInfo == NULL) {
printf ("no font found\n");
exit (0);
}
id = fontInfo->fid;
first = fontInfo->min_char_or_byte2;
last = fontInfo->max_char_or_byte2;
base = glGenLists(last+1);
if (base == 0) {
printf ("out of display lists\n");
exit (0);
}
glXUseXFont(id, first, last-first+1, base+first);
}
/******************************************************
* printString
******************************************************/
void printString(const char *s)
{
glListBase(base);
glCallLists(strlen(s), GL_UNSIGNED_BYTE, (unsigned char *)s);
}
/******************************************************
* getColormap
******************************************************/
Colormap getColormap ( XVisualInfo *vis){
Status stat;
XStandardColormap *sCm;
Colormap cm;
int i;
int numCmaps;
if ( vis->c_class != TrueColor ){
printf ("No support for TrueColor!");
exit(1);
}
stat = XmuLookupStandardColormap(disp, vis->screen, vis->visualid,
vis->depth,XA_RGB_DEFAULT_MAP, False, True);
if (stat == 1) {
stat = XGetRGBColormaps( disp, RootWindow(disp, vis->screen),
&sCm, &numCmaps,
XA_RGB_DEFAULT_MAP);
if (stat == 1)
for( i = 0; i < numCmaps; i++ )
if( sCm[i].visualid == vis->visualid) {
cm = sCm[i].colormap;
XFree(sCm);
return cm;
}
}
cm = XCreateColormap (disp, RootWindow(disp,vis->screen),
vis->visual, AllocNone);
return cm;
}
/******************************************************
* openWindow
******************************************************/
JNIEXPORT void JNICALL
Java_fi_iki_lukka_ZZOpenGLGraphics_openWindow( JNIEnv *env,
jobject obj,
jint width,
jint height)
{
XVisualInfo *vi;
Colormap cm;
XSetWindowAttributes xswa;
XWMHints *wmHints;
Atom wmDeleteWindow;
GLXContext cx;
char *display = NULL;
/** connect to X server **/
disp = XOpenDisplay(display);
// FIX ME
if ( disp == NULL ) exit(1);
printf("__C__: openWindow\n");
/** check for glx */
if ( ! glXQueryExtension(disp, NULL, NULL))
// maybe should use some constants
return;// 2;
/** visual & colormap **/
vi = glXChooseVisual(disp, DefaultScreen(disp),args );
if ( ! vi ){
// no doublebuffering
vi = glXChooseVisual(disp, DefaultScreen(disp),&args[1] );
if ( ! vi ) exit(1);
db = GL_FALSE;
}
cm = getColormap(vi);
/** GL rendering context **/
cx = glXCreateContext(disp, vi, NULL, GL_TRUE);
if ( cx == NULL )
exit(1);
/* some hints etc */
xswa.colormap = cm;
xswa.border_pixel = 0;
xswa.event_mask = ExposureMask|ButtonPressMask|KeyPressMask;
sizeHints.width = width;
sizeHints.height = height;
sizeHints.x = 10;
sizeHints.y = 10;
win = XCreateWindow(disp, RootWindow(disp,vi->screen),
sizeHints.x, sizeHints.y,
width, height, 0, vi->depth, InputOutput,
vi->visual, CWEventMask|CWBorderPixel|CWColormap, &xswa);
wmDeleteWindow = XInternAtom(disp, "WM_DELETE_WINDOW", False);
XSetWMProtocols(disp, win, &wmDeleteWindow,1);
XSetStandardProperties(disp, win, "test", "Testi",
None, None, None, &sizeHints);
wmHints = XAllocWMHints();
wmHints->initial_state = NormalState;
wmHints->flags = StateHint;
XSetWMHints(disp, win, wmHints);
/* bind context to window */
glXMakeCurrent(disp, win, cx);
glEnable ( GL_DEPTH_TEST );
glEnable ( GL_ALPHA_TEST );
glDisable ( GL_DITHER );
glDisable ( GL_LIGHTING );
glDisable ( GL_FOG );
glDisable ( GL_TEXTURE_2D );
glDisable ( GL_CULL_FACE );
glDisable ( GL_SCISSOR_TEST );
glDisable ( GL_STENCIL_TEST );
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(65, (GLfloat) width
/ (GLfloat) height, 1, 1000);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
gluLookAt(0, 0, 100, 0, 0, 0, 0, 1, 0);
glMatrixMode(GL_MODELVIEW);
XMapWindow(disp,win);
glXSwapBuffers(disp, win);
makeRasterFont(disp);
}
/******************************************************
* drawLine
******************************************************/
JNIEXPORT void JNICALL
Java_fi_iki_lukka_ZZOpenGLGraphics_drawLine(JNIEnv *env, jobject obj,
jint x1, jint y1,
jint x2, jint y2){
printf("__C__: drawLine\n");
glBegin(GL_LINES);
glVertex3d( x1, y1, 0 );
glVertex3d( x2, y2, 0 );
glEnd();
}
JNIEXPORT void JNICALL
Java_fi_iki_lukka_ZZOpenGLGraphics_drawRect(JNIEnv *env, jobject obj,
jint x, jint y,
jint width, jint height){
printf("__C__: drawRect\n");
glBegin(GL_QUADS);
glVertex3d( x, y, 0 );
glVertex3d( x, y+height, 0 );
glVertex3d( x+width, y+height, 0 );
glVertex3d( x+width, y, 0 );
glEnd();
}
JNIEXPORT void JNICALL
Java_fi_iki_lukka_ZZOpenGLGraphics_drawPoint(JNIEnv *env, jobject obj,
jint x, jint y);
JNIEXPORT void JNICALL
Java_fi_iki_lukka_ZZOpenGLGraphics_drawText(JNIEnv *env, jobject obj,
jint x, jint y,
jstring text, jint size){
int s;
//int l;
const char *str = (const char *)env->GetStringUTFChars( text, 0 );
printf("str = %s\n", str);
s = env->GetStringLength( text);
// Check the size
printf("s = %d\n", s);
glLoadIdentity();
/*
//
// glut stroke fonts
glTranslatef(x,y,0);
glScalef(0.03,0.03,0.03);
for(l = 0; l < s; l++){
glutStrokeCharacter(GLUT_STROKE_ROMAN , str[l]);
glTranslatef(glutStrokeWidth(GLUT_STROKE_ROMAN,str[l]),0,0);
}
*/
printf("__C__: drawText\n");
//glColor3f(1,1,1);
glLoadIdentity();
FTFace face;
if( ! face.open("/dos/winnt/Fonts/couri.ttf") ){
printf("unable to open ttf file");
return ;
}
GLTTOutlineFont font(&face);
int point_size= size;
if( ! font.create(point_size) ){
printf("unable to create outline font");
return ;
}
glTranslatef(x,y,0);
//glRotatef(45,0,1,0);
//font.setPrecision(4);
font.output( str );
// bitmap fonts
//printString(str);
glLoadIdentity();
env->ReleaseStringUTFChars( text, 0);
}
JNIEXPORT void JNICALL
Java_fi_iki_lukka_ZZOpenGLGraphics_drawingColor(JNIEnv *env, jobject obj,
jdouble r, jdouble g,
jdouble b, jdouble a){
glColor4d(r,g,b,a);
}
JNIEXPORT void JNICALL
Java_fi_iki_lukka_ZZOpenGLGraphics_drawArrow(JNIEnv *env, jobject obj,
jint x, jint y,
jint dx, jint dy,
jint dz){
glLoadIdentity();
glScalef(dx,dy,dz);
glBegin(GL_LINES);
glVertex3f(x,y,0);
glVertex3f(x,y-1,0);
glVertex3f(x,y,0);
glVertex3f(x+2,y-2,0);
glVertex3f(x,y,0);
glVertex3f(x+1,y,0);
glEnd();
glLoadIdentity();
}
/******************************************************
* swapBuffers
******************************************************/
JNIEXPORT void JNICALL
Java_fi_iki_lukka_ZZOpenGLGraphics_swapBuffers(JNIEnv *env,
jobject obj){
printf("__C__: swapBuffers\n");
glXSwapBuffers(disp,win);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
}
/******************************************************
* checkEvents
******************************************************/
JNIEXPORT void JNICALL
Java_fi_iki_lukka_ZZOpenGLGraphics_checkEvents( JNIEnv *env, jobject obj){
XKeyEvent *e_key;
XButtonEvent *e_but;
XConfigureEvent *e_conf;
jclass cls = env->GetObjectClass( obj );
jmethodID key_id = env->GetMethodID( cls,
"addKeyEvent", "(II)V");
jmethodID button_id = env->GetMethodID( cls,
"addButtonEvent", "(IIII)V");
jmethodID conf_id = env->GetMethodID( cls,
"configureEvent", "(II)V");
printf("__C__: Check events\n");
if ( button_id == 0 || key_id == 0 ) {
printf ("no method id\n");
return ;
}
do{
int ch;
int type = 0;
XEvent event;
XNextEvent(disp, &event);
switch ( event.type ){
case ConfigureNotify:
printf("ConfNotify");
env->CallVoidMethod( obj, conf_id,
e_conf->width, e_conf->height);
break;
case ButtonPress:
e_but = (XButtonEvent *) &event;
env->CallVoidMethod( obj, button_id,
e_but->button, e_but->x, e_but->y, 0);
break;
case KeyPress:
e_key = (XKeyEvent *) &event;
ch = (int )XLookupKeysym(e_key,0);
env->CallVoidMethod( obj, key_id, ch, type);
break;
default:
;
}
} while( XPending( disp ) );
return ;
}

View File

@@ -0,0 +1,606 @@
/*
ZZGraphics.java
*
* Copyright (c) 2000, Ted Nelson, Tuomas Lukka and Vesa Parkkinen
*
* 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 Vesa Parkkinen
*/
package org.gzigzag;
import java.awt.*;
import java.util.*;
import java.awt.event.*;
/** A class that implements the ZZGraphics interface using OpenGL.
* Tjl's comments:
* <ul>
* <li> You DON'T want to derive everything from OGLColorThing: that
* slows down rendering. Note how it's done in ZZCanvas: there's
* a ColorThing which sets the foreground/background color which
* is then used.
*
* A state machine... Well, whatever you want.
* Doesn't that somewhat dictate the ordering of drawing,
* what if for some reason (optimization etc.) I want to
* draw the in different order ? I admit it slows rendering,
* but I still would like to have objects with color, not just
* global pens to use in drawing, at least in the object level.
* The implementation of rendering is a completely different thing,
* and shouldn't dictate design issues.
* The actual rendering is unbeliavably simple at the moment,
* but i just wanted to get the java-C-java pipeline to work. /vp
*
* Tjl: In that case, put in a reference to a reusable OGLColorThing
* (in Design Patterns, this is called a flyweight).
* the order of drawing is an excellent point: I was still thinking
* in terms of java.awt.Graphics where order is visible; if we have
* a Z-buffer, that's right. However, if we don't use a Z-buffer, the
* order of rendering is really important.
*
* OTOH: for drawing order, using the color makes sense since in
* some cases changing the color (or material) in OpenGL
* can be one of the slowest operations.
*
* vp: That's why I would like to have attributes of objects to be
* within objects, so i could _easily_ handle them in the order
* that makes most sense at that moment.
*
* <li> For Colors, extend java.awt.Color with alpha - in Java1.2, this
* is already done.
*
* Why ? I just need 4 doubles. Of course there will be methods
* to use Color, but internally i'd like to keep color as
* doubles /vp
*
* Tjl: double = 8 bytes. 4 doubles = 32 bytes. java.awt.Color = 4 bytes.
* first of all, we want to avoid float arithmetic so using bytes or
* an integer would be better. glColor3b can be much faster.
*
* vp: well it's pretty much same to me if it is a byte, float
* or double, but I would like to put it to the format it is used
* at creation time rather than in rendering time.
*
* <li> Why does colorthing have coordinates?
*
* Because a Thing is always in space somewhere. They are objects,
* not just some global "pen swithes". /vp
*
* Tjl: see above for how to handle ColorThing - that way it doesn't
* have coordinates.
*
* One big question is: *DO* we really want actual "models" or just
* drawing things?
* Both the layer above and the layer below are about drawing with a
* pen - why have a layer with models in between?
*
* vp: As long as we already have objects why don't use them.
* It gives much more flexibility when trying to do more complex
* things. BTW, What is the layer above that is about drawing with a
* pen?
* If we would strip the awt from zzcanvas, and added a simple way
* to use any ZZGraphics, then this wouldn't be an issue: you could
* do it the way you wanted in ZZCanvas. And that is the way I think
* it should be done.
*
*
* <li> Basically, check out how ZZCanvas does things and do the same.
* Actually, we might want to think about separating the class
* structure in a way as to have an abstract base class for graphic
* beams and then two implementations, one for opengl and the other
* for awt. Or even have things implement ZZOpenGLThing interface.
* ZZCanvas is pretty abstract.
*
* I don't think so, ZZCanvas is way
* too tightly connected to awt. If one could bring his own graphics,
* with some basic methods, drawCell, drawLink etc., then it would
* be good. In fact that is the way I think it should be done. /vp
*
* Tjl: Explain further. The connection to awt is actually limited to
* the methods render*.
*
* vp: Exactly. We should have ZZCanvas(zzgraphics g), so we could use
* zzcanvas with any graphics we would like to implement. All rendering
* would go through that zzgraphics. So every render method
* should have something like g.drawLine, where g is zzgraphics not
* graphics.
*
* <li> if you extend Component, do you need addKeyListener and
* addMouseListener?
*
* If I want to throw my own keyevents, yes./vp
*
* they are already implemented there.
*
* Is there somewhere a method to fire your own key & mouse events? /vp
*
* Alternatively, not deriving from Component might be good.
*
* I know, I should have added a Component and used that to fire
* those events... /vp
*
* java.awt.Component.processEvent(KeyEvent) /vp
*
* </ul>
*/
public class ZZOpenGLGraphics extends Component implements ZZGraphics, Runnable {
String rcsid = "$Id: ZZOpenGLGraphics.java,v 1.9 2000/11/05 12:49:39 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); }
KeyListener actionListener = null;
public void addKeyListener(KeyListener l) {
actionListener = AWTEventMulticaster.add(actionListener, l);
}
public void removeKeyListener(KeyListener l) {
actionListener = AWTEventMulticaster.remove(actionListener, l);
}
public void processKeyEvent(KeyEvent e) {
if (actionListener != null) {
actionListener.keyPressed(e);
}
}
MouseListener mouseListener = null;
public void addMouseListener(MouseListener l) {
mouseListener = AWTEventMulticaster.add(mouseListener, l);
}
public void removeMouseListener(MouseListener l) {
mouseListener = AWTEventMulticaster.remove(mouseListener, l);
}
public void processMouseEvent(MouseEvent e) {
if (mouseListener != null){
mouseListener.mouseClicked(e);
}
}
int GLcontext = 0;
int window = 0;
int display = 0;
int font_Size = 10;
/* just testing */
int cx = 0;
int cy = 0;
int cz = 50;
Vector things = new Vector();
public abstract class OGLThing {
int x;
int y;
OGLThing(int x, int y ){
this.x = x;
this.y = y;
}
OGLThing( ){
x = 0;
y = 0;
}
public void coords(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() { return x; }
public int getYs() { return y; }
// rendes to this context
public abstract void render();
}
public class OGLColorThing extends OGLThing{
float r;
float g;
float b;
float a;
OGLColorThing(int x, int y, float r, float g, float b, float a){
super(x,y);
this.r = r;
this.g = g;
this.b = b;
this.a = a;
}
OGLColorThing(){
super();
this.r = 1;
this.g = 1;
this.b = 1;
this.a = 1;
}
OGLColorThing(int x, int y){
super(x,y);
this.r = 1;
this.g = 1;
this.b = 1;
this.a = 1;
}
OGLColorThing(Color c){
super(0,0);
setColor(c);
}
public void setColor(Color c){
}
public void setColor(int r, int g, int b, int a){
this.r = r;
this.g = g;
this.b = b;
this.a = a;
}
public void render(){
p("COLOR: RENDER\n");
/* this is just a temporary solution,
add checking of color */
drawingColor(r,g,b,a);
}
}
public abstract class OGLCell extends OGLColorThing{
ZZCell c;
public OGLCell(){
super();
c = null;
}
public OGLCell(int x, int y, ZZCell c){
super(x,y);
this.c = c;
}
public OGLCell( ZZCell c ){
super();
this.c = c;
}
}
public class OGL2DCell extends OGLCell {
int width;
int height;
public OGL2DCell(){
super();
width = 0;
height = 0;
}
public OGL2DCell(int x, int y, int width, int height, ZZCell cell){
super(x,y,cell);
this.width = width;
this.height = height;
}
public void render(){
super.render();
p("CELL: RENDER" + x + " " +y);
drawRect(x,y,width,height);
if( c != null ) {
drawingColor(0,0,0,1);
drawText(x+2, y+2, c.getText(),10);
}
}
}
public class OGLText extends OGLColorThing{
int size;
String text;
public OGLText(int x, int y, String txt){
super(x,y);
text = txt;
size = 10;
}
public void render(){
//super.render();
drawText(x, y, text, size );
}
}
public class OGLLink extends OGLColorThing{
int x2;
int y2;
OGLLink(int x1, int y1, int x2, int y2){
super(x1,y1);
this.x2 = x2;
this.y2 = y2;
}
public void render(){
super.render();
drawLine(super.x,super.y, x2, y2);
}
}
public class OGLLine extends OGLColorThing{
int x2;
int y2;
OGLLine(int x1, int y1, int x2, int y2){
super(x1,y1);
this.x2 = x2;
this.y2 = y2;
}
public void render(){
super.render();
drawLine(super.x,super.y, x2, y2);
}
}
public class OGLMark extends OGLColorThing{
ZZCell c;
int h;
OGLMark(int x1, int y1, int h, ZZCell c){
super(x1,y1);
this.c = c;
this.h = h;
}
public void render(){
super.render();
drawLine(super.x,super.y, x, y+h);
}
}
class OGLArrow extends OGLColorThing{
// Hmm...
int dir_x;
int dir_y;
int dir_z;
public OGLArrow(int x, int y){
super(x,y);
dir_x = 2;
dir_y = 2;
dir_z = 1;
}
public void render(){
super.render();
drawArrow(super.x,super.y, dir_x, dir_y, dir_z);
}
}
public Dimension getSize(){
return null;
}
public Dimension getDefaultCellSize(ZZCell c){
return null;
}
public void putCell(ZZCell c, int x, int y, int w, int h, String style){
things.addElement(new OGL2DCell(x,y,w,h,c));
}
public void putLinks(String dim, float dx, float dy){
}
// public void putBeams(ZZCanvasTextSpanSet set1, ZZCanvasTextSpanSet set2){
//
// }
public void setColor(Color c){}
public int getDefaultFontSize(){ return 0;}
public FontMetrics getFontMetrics(Font f){ return null;}
public void setFont(Font f){}
public void putPolyLine(int x1, int y1, int x2, int y2, String style){}
public void putText(String s, int x, int y){
things.addElement(new OGLText(x,y,s));
}
public void putText(String s, int x, int y, int size){
things.addElement(new OGLText(x,y,s));
}
/*
public void putText(String s, int x, int y, int z){
things.addElement(new OGLText(x,y,z,s));
}
*/
public Object putSpan(Span s, String str, ZZCell c, int x, int y,
int w, int h, int xoffs, int yoffs,
ZZCanvasTextSpanSet collect,
Object prev,
Font f, FontMetrics fm){
return null;}
public void putTextMark(int x, int y, int h, ZZCell mkc){
things.addElement(new OGLMark(x,y,h, mkc));
}
public void putLine(int x1, int y1, int x2, int y2, String style){
//drawLine(x1, y1, x2, y2);
things.addElement(new OGLLine(x1,y1,x2,y2));
}
public void putCoordNames(String[] names){}
public void putArrow( int x1, int y1,
int x2, int y2,
Color intern, String style){
things.addElement(new OGLArrow(x1,y1));
}
// public void putDragCursor(ZZGraphics.DragCursor dc, int x, int y){}
// public class OpenGLDragCursor implements ZZGraphics.DragCursor {
// public boolean accept(Object o){ return false; }
// }
static {
System.loadLibrary("zz3d");
}
public void render(){
p("RENDER:");
for (Enumeration e = things.elements() ; e.hasMoreElements() ;) {
((OGLThing)e.nextElement()).render();
}
swapBuffers();
}
private Thread thread = null;
public void start() {
if (thread == null) {
thread = new Thread(this, "render");
thread.start();
}
}
public void run() {
Thread myThread = Thread.currentThread();
p("RUN:");
while (thread == myThread) {
checkEvents();
render();
try {
Thread.sleep(100);
} catch (InterruptedException e){
// the VM doesn't want us to sleep anymore,
// so get back to work
}
}
}
void addKeyEvent(int key, int type){
p("KEY_EVENT: " + (char)key + " " + type);
// XXX add missing info: time, modifiers ...
processKeyEvent(new KeyEvent(this,1000,1,0,key,(char)key));
}
void addButtonEvent(int button, int x, int y, int modifiers){
p("BUTTON_EVENT: " + button + " " + x + y);
processMouseEvent(new MouseEvent(this,1001,1,0,x,y,1,false));
}
void configureEvent(int x, int y){
p("CONFIGURE_EVENT:" + x + " " + y);
}
/******************/
/* NATIVE METHODS */
/******************/
/**
* This is supposed to create a native window, put right values
* to variales in this class, create glx context...
*
*/
public native void openWindow( int width, int height );
public native void drawLine( int x1, int y1, int x2, int y2 );
public native void draw3DLine( int x1, int y1, int z1,
int x2, int y2, int z2 );
public native void drawRect( int x, int y, int width, int height );
public native void draw2DPoint( int x, int y );
public native void draw3DPoint( int x, int y, int z );
public native void drawText( int x, int y, String text, int size );
public native void draw3DText( int x, int y, int z,
String text, int size );
public native void drawingColor( double r, double g, double b, double a );
public native void drawArrow(int x, int y,
int dir_x, int dir_y, int dir_z);
public native void draw3DArrow(int x, int y, int z,
int dir_x, int dir_y, int dir_z);
public native void swapBuffers();
public native void checkEvents();
public native void setCamera( int x, int y, int z,
int ex, int ey, int ez,
int lx, int ly, int lz );
}

View File

@@ -0,0 +1,125 @@
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class fi_iki_lukka_ZZOpenGLGraphics */
#ifndef _Included_fi_iki_lukka_ZZOpenGLGraphics
#define _Included_fi_iki_lukka_ZZOpenGLGraphics
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: fi_iki_lukka_ZZOpenGLGraphics
* Method: openWindow
* Signature: (II)V
*/
JNIEXPORT void JNICALL Java_fi_iki_lukka_ZZOpenGLGraphics_openWindow
(JNIEnv *, jobject, jint, jint);
/*
* Class: fi_iki_lukka_ZZOpenGLGraphics
* Method: drawLine
* Signature: (IIII)V
*/
JNIEXPORT void JNICALL Java_fi_iki_lukka_ZZOpenGLGraphics_drawLine
(JNIEnv *, jobject, jint, jint, jint, jint);
/*
* Class: fi_iki_lukka_ZZOpenGLGraphics
* Method: draw3DLine
* Signature: (IIIIII)V
*/
JNIEXPORT void JNICALL Java_fi_iki_lukka_ZZOpenGLGraphics_draw3DLine
(JNIEnv *, jobject, jint, jint, jint, jint, jint, jint);
/*
* Class: fi_iki_lukka_ZZOpenGLGraphics
* Method: drawRect
* Signature: (IIII)V
*/
JNIEXPORT void JNICALL Java_fi_iki_lukka_ZZOpenGLGraphics_drawRect
(JNIEnv *, jobject, jint, jint, jint, jint);
/*
* Class: fi_iki_lukka_ZZOpenGLGraphics
* Method: draw2DPoint
* Signature: (II)V
*/
JNIEXPORT void JNICALL Java_fi_iki_lukka_ZZOpenGLGraphics_draw2DPoint
(JNIEnv *, jobject, jint, jint);
/*
* Class: fi_iki_lukka_ZZOpenGLGraphics
* Method: draw3DPoint
* Signature: (III)V
*/
JNIEXPORT void JNICALL Java_fi_iki_lukka_ZZOpenGLGraphics_draw3DPoint
(JNIEnv *, jobject, jint, jint, jint);
/*
* Class: fi_iki_lukka_ZZOpenGLGraphics
* Method: drawText
* Signature: (IILjava/lang/String;I)V
*/
JNIEXPORT void JNICALL Java_fi_iki_lukka_ZZOpenGLGraphics_drawText
(JNIEnv *, jobject, jint, jint, jstring, jint);
/*
* Class: fi_iki_lukka_ZZOpenGLGraphics
* Method: draw3DText
* Signature: (IIILjava/lang/String;I)V
*/
JNIEXPORT void JNICALL Java_fi_iki_lukka_ZZOpenGLGraphics_draw3DText
(JNIEnv *, jobject, jint, jint, jint, jstring, jint);
/*
* Class: fi_iki_lukka_ZZOpenGLGraphics
* Method: drawingColor
* Signature: (DDDD)V
*/
JNIEXPORT void JNICALL Java_fi_iki_lukka_ZZOpenGLGraphics_drawingColor
(JNIEnv *, jobject, jdouble, jdouble, jdouble, jdouble);
/*
* Class: fi_iki_lukka_ZZOpenGLGraphics
* Method: drawArrow
* Signature: (IIIII)V
*/
JNIEXPORT void JNICALL Java_fi_iki_lukka_ZZOpenGLGraphics_drawArrow
(JNIEnv *, jobject, jint, jint, jint, jint, jint);
/*
* Class: fi_iki_lukka_ZZOpenGLGraphics
* Method: draw3DArrow
* Signature: (IIIIII)V
*/
JNIEXPORT void JNICALL Java_fi_iki_lukka_ZZOpenGLGraphics_draw3DArrow
(JNIEnv *, jobject, jint, jint, jint, jint, jint, jint);
/*
* Class: fi_iki_lukka_ZZOpenGLGraphics
* Method: swapBuffers
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_fi_iki_lukka_ZZOpenGLGraphics_swapBuffers
(JNIEnv *, jobject);
/*
* Class: fi_iki_lukka_ZZOpenGLGraphics
* Method: checkEvents
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_fi_iki_lukka_ZZOpenGLGraphics_checkEvents
(JNIEnv *, jobject);
/*
* Class: fi_iki_lukka_ZZOpenGLGraphics
* Method: setCamera
* Signature: (IIIIIIIII)V
*/
JNIEXPORT void JNICALL Java_fi_iki_lukka_ZZOpenGLGraphics_setCamera
(JNIEnv *, jobject, jint, jint, jint, jint, jint, jint, jint, jint, jint);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,76 @@
/*
PaneView.zob
*
* 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 Benjamin Fallenstein
*/
package org.gzigzag;
import java.util.*;
import java.awt.*;
/** A view that shows different other views on different panes.
* Like the SplitNileView, but more generally useful. Currently, exactly two
* panes are shown.
*/
public class PaneView implements FlobView, ZOb {
public static final String rcsid = "$Id: PaneView.zob,v 1.1 2001/01/20 08:52:40 bfallenstein Exp $";
public static final boolean dbg = true;
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 space to leave between the two panes. */
int space
= 20;
}
public void raster(FlobSet into, FlobFactory fact,
ZZCell win, String[] dims, ZZCell accursed) {
ZZCell lpane = win.s("d.panes", 1);
ZZCell rpane = win.s("d.panes", 2);
if(rpane == null)
throw new ZZError("No panes found for PaneView");
ZZCell leftacc = ZZCursorReal.get(lpane);
ZZCell rightacc = ZZCursorReal.get(rpane);
ZZCell lapp = lpane.h("d.pane-app");
ZZCell rapp = rpane.h("d.pane-app");
ZZCell linkapp = win.h("d.pane-link-app");
Dimension size = new Dimension(into.getSize());
size.width = (size.width - space) / 2;
FlobSet left = into.create(size), right = into.create(size);
FlobView view = ApplitudeMgr.getView(lapp);
view.raster(left, fact, lpane, dims, leftacc);
view = ApplitudeMgr.getView(rapp);
view.raster(right, fact, rpane, dims, rightacc);
into.fetch(left, 0, 0, 0);
into.fetch(right, size.width + space, 0, 0);
view = ApplitudeMgr.getView(linkapp);
view.raster(into, fact, win, dims, accursed);
}
}

51
Modules/prez/Prez.java Normal file
View File

@@ -0,0 +1,51 @@
/*
Prez.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.module;
import org.gzigzag.*;
import java.awt.*;
import java.util.*;
import java.io.*;
/** A simple presentation module.
*/
public class Prez {
public static final String rcsid = "$Id: Prez.java,v 1.4 2000/09/19 10:32:03 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); }
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) {
}
public ZOb newZOb(String id) {
if(id.equals("R"))
return new PrezRaster();
return null;
}
};
}

173
Modules/prez/PrezRaster.zob Normal file
View File

@@ -0,0 +1,173 @@
/*
Prez.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 and Asko Soukka
*/
package org.gzigzag.module;
import org.gzigzag.*;
import java.awt.*;
import java.util.*;
import java.io.*;
/** A simple presentation raster.
* The structure is described along three dimensions:
* hierarchy, sibling and cross-reference (x, y and z).
* On these, the hierarchy is arranged as a corner list with an empty
* corner cell, and the cross-references are simply siblings
* connected.
*/
public class PrezRaster implements FlobView, ZOb {
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 vstream raster used for the header. */
ZOb hdrvs // VStreamRaster
= new RankTextView() {{
width = 650;
dim = "d.foo";
}};
/** The vstream raster used for the items. */
ZOb txtvs // RankTextView
= new RankTextView() {{
width = 500;
dim = "d.foo";
}};
/** The vstream raster used for the crossrefs. */
ZOb xrefvs // RankTextView
= new RankTextView() {{
width = 500;
dim = "d.foo";
}};
/** The amount to shift the header. */
int hdrindent
= 30;
/** The amount to shift the items. */
int indent
= 50;
/** The amount to space the items. */
int space
= 30;
int topmargin
= 120;
int afterhdr
= 0;
ScalableFont hdrfont
= new ScalableFont("SansSerif", Font.PLAIN, 32);
ScalableFont txtfont
= new ScalableFont("SansSerif", Font.PLAIN, 24);
ScalableFont xreffont
= new ScalableFont("SansSerif", Font.PLAIN, 10);
int hdrwidth
= 650;
int txtwidth
= 500;
}
String next = "d.2";
String hier = "d.1";
String cross = "d.3";
public void raster(FlobSet into, FlobFactory fact,
ZZCell view, String[] dims, ZZCell accursed) {
hier = dims[0];
next = dims[1];
cross = dims[2];
ZZCell hdr = null;
/* Something to work with circular ranks.
* Goes rank backwards and gets the first available cell
* on the negative direction on the hier-dimension.
* Otherwise gets the accursed cell. */
hdr = accursed.s(hier, -1);
int i = -1;
while (hdr == null) {
if (accursed.s(next, i) == null) break;
hdr = accursed.s(next, i).s(hier, -1);
if (i < -20) break;
i--;
}
if (hdr == null) hdr = accursed;
RankTextView hdrvs = (RankTextView)this.hdrvs;
RankTextView txtvs = (RankTextView)this.txtvs;
RankTextView xrefvs = (RankTextView)this.xrefvs;
hdrvs.font = hdrfont;
txtvs.font = txtfont;
xrefvs.font = xreffont;
hdrvs.width = hdrwidth;
txtvs.width = txtwidth;
hdrvs.readParams(null);
txtvs.readParams(null);
xrefvs.readParams(null);
int y = topmargin;
Rectangle bds = hdrvs.raster(into, hdr, 0, false,
hdrindent, y);
p("Raster 1: "+bds);
y += bds.height + afterhdr;
ZZCell cur = hdr.s(hier, 1);
if(cur == null) return;
LoopDetector l = new LoopDetector();
while(true) {
cur = cur.s(next, 1);
if(cur == null) break;
if(cur == hdr.s(hier, 1)) break;
l.detect(cur);
bds = txtvs.raster(into, cur, 0, false, indent, y);
p("Raster n: "+bds);
// indicate that there is more
if(cur.s(hier, 1) != null) {
into.add(new LineDecor(bds.x+bds.width, bds.y,
bds.x+bds.width, bds.y+bds.height,
Color.blue, 1));
}
if(cur.s(cross, -1) != null)
xrefvs.raster(into, cur.s(cross,-1),
0, false, 400, bds.y-15);
if(cur.s(cross, 1) != null)
xrefvs.raster(into, cur.s(cross,1),
0, false, 400, bds.y+bds.height+5);
y += bds.height + space;
}
}
}
// vim: set syntax=java :

View File

@@ -0,0 +1,144 @@
/*
VCServlet.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.module;
import org.gzigzag.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
/** A Virtual Community demo servlet.
*/
public class VCServlet extends ZZServlet {
public static final String rcsid = "$Id: VCServlet.java,v 1.2 2001/02/28 03:02:56 tjl Exp $";
String getURL(ZZCell c) {
return "org.gzigzag.module.VCServlet?"+c.getID();
}
void printAuthor(ZZCell txt, PrintWriter wr) {
ZZCell h = txt.h("d.author", true);
if(h != null) {
wr.print("<a style=\"color: #FF0000;\" href=\""+getURL(h)
+"\">"+h.getText()+"</a>");
}
}
void printmsg(ZZCell h, PrintWriter wr) {
printAuthor(h, wr);
wr.print(": ");
wr.print("<a href=\""+getURL(h) + "\">"+ h.getText() + "</a>");
}
void printRefs(ZZCell thing, PrintWriter wr) {
wr.print("<p>Referenced in: <ul>");
while((thing = thing.s("d.kahva")) != null) {
ZZCell h = thing.h("d.text");
wr.print("<li>");
printmsg(h, wr);
}
wr.print("</ul>\n");
}
void printAuthored(ZZCell thing, PrintWriter wr) {
wr.print("<p>Messages written: <ul>");
while((thing = thing.s("d.author")) != null) {
ZZCell h = thing.h("d.text");
wr.print("<li>");
wr.print("<a href=\""+getURL(h) + "\">"+ h.getText() + "</a>");
}
wr.print("</ul>\n");
}
void printReplies(ZZCell thing, PrintWriter wr) {
thing = thing.s("d.replies");
if(thing == null) return;
wr.print("<p>Replies: <ul>");
while((thing = thing.s("d.replies-list")) != null) {
ZZCell h = thing.h("d.text");
wr.print("<li>");
printmsg(h, wr);
}
wr.print("</ul>\n");
}
void printText(ZZCell start, PrintWriter wr) {
wr.print("<h1>"+start.getText()+"</h1>");
ZZCell im = start.h("d.images", true);
if(im != null) {
wr.print("<img src=\""+im.getText()+"\">");
}
printAuthor(start, wr);
wr.print("<p>");
ZZCell orig = start;
while((start = start.s("d.text")) != null) {
ZZCell h = start.h("d.kahva", true);
String txt = start.getText();
if(h != null) {
txt = "<a href=\""+getURL(h) + "\">"+ txt + "</a>";
}
wr.print(txt);
}
if(orig.s("d.author", -1) == null)
printAuthored(orig, wr);
ZZCell inreply = orig.h("d.replies-list").s("d.replies",-1);
if(inreply != null) {
wr.print("<p>In reply to ");
printmsg(inreply, wr);
}
printReplies(orig, wr);
printRefs(orig, wr);
}
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException {
try {
synchronized(space) {
// resp.getWriter().print("HELLO\n\n!!\n\n");
String s = req.getQueryString();
PrintWriter wr = resp.getWriter();
wr.print("HELLO\n\n!!\n\n Query: '"+s+"'\n");
ZZCell c;
if(s == null || s.equals(""))
c = space.getHomeCell().s("d.1");
else
c = space.getCellByID(s);
wr.print("<br>Cell content: '"+c.getText()+"'\n");
printText(c, wr);
wr.close();
}
} catch(Exception e) {
throw new ServletException("doGet: ", e);
}
}
}

View File

@@ -0,0 +1,78 @@
/*
ZZServlet.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.module;
import org.gzigzag.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
/** A base class for servlets based on ZZ spaces.
*/
public class ZZServlet extends HttpServlet {
public static final String rcsid = "$Id: ZZServlet.java,v 1.1 2001/01/17 14:27:20 tjl Exp $";
static Hashtable spaces = new Hashtable();
static Object lock = new Object();
static ZZSpace getSpace(String name) {
synchronized(lock) {
ZZSpace s = (ZZSpace)spaces.get(name);
if(s == null) {
File f = new File(name);
s = new ZZCacheDimSpace(new DirStreamSet(f));
spaces.put(name, s);
}
return s;
}
}
ZZSpace space;
public void init(ServletConfig config) throws ServletException {
synchronized(lock) {
String s = config.getInitParameter("space");
if(s == null) {
// throw new ServletException("No space specified!");
s = "/tmp/testspace";
}
space = getSpace(s);
}
}
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException {
try {
synchronized(space) {
resp.getWriter().print("HELLO\n\n!!\n\n");
}
} catch(Exception e) {
throw new ServletException("doGet: ", e);
}
}
}

View File

@@ -0,0 +1,4 @@
#!/bin/sh
# java com.mortbay.HTTP.Configure.ServletServer 8080 . .
java com.mortbay.Jetty.Server ../Modules/servlet/zzserv2.prp

View File

@@ -0,0 +1,42 @@
*.CLASS : com.mortbay.HTTP.HttpServer
*.LISTENER.*.CLASS : com.mortbay.HTTP.HttpListener
*.*.Log.CLASS : com.mortbay.HTTP.Handler.LogHandler
*.*.Auth.CLASS : com.mortbay.HTTP.Handler.BasicAuthHandler
*.*.Alias.CLASS : com.mortbay.HTTP.Handler.TranslateHandler
*.*.Filter.CLASS : com.mortbay.HTTP.Handler.FilterHandler
*.*.Html.CLASS : com.mortbay.HTTP.Filter.HtmlFilter
*.*.Param.CLASS : com.mortbay.HTTP.Handler.ParamHandler
*.*.Session.CLASS : com.mortbay.HTTP.Handler.SessionHandler
*.*.Servlet.CLASS : com.mortbay.HTTP.Handler.ServletHandler
*.*.File.CLASS : com.mortbay.HTTP.Handler.FileHandler
*.*.Forward.CLASS : com.mortbay.HTTP.Handler.ForwardHandler
*.*.NotFound.CLASS : com.mortbay.HTTP.Handler.NotFoundHandler
*.*.Proxy.CLASS : com.mortbay.HTTP.Handler.ProxyHandler
*.*.DefaultEx.CLASS : com.mortbay.HTTP.Handler.DefaultExceptionHandler
*.*.TerseEx.CLASS : com.mortbay.HTTP.Handler.TerseExceptionHandler
*.*.ZZServer.CLASS : org.gzigzag.module.ZZServlet
*.*.Servlet.PROPERTY.SERVLET.ZZServer.CLASS : org.gzigzag.module.ZZServlet
*.*.Servlet.PROPERTY.SERVLET.ZZServer.PROPERTY.space : /home/tjl/tspc
*.*.Servlet.PROPERTY.CLASSPATH : /home/tjl/gzigzag/Java/org/gzigzag:/home/tjl/gzigzag/Java/org/gzigzag/module:/home/tjl/gzigzag/Java/
SERVERS : main
main.root.PATHS : /
main.LISTENER.all.ADDRS : 0.0.0.0:8080;127.0.0.1:8888
main.LISTENERS : all
main.STACKS : root
main.root.HANDLERS : Servlet;NotFound
*.*.Servlet.PROPERTY.PATHS : /
*.*.Servlet.PROPERTY.Loader : com.mortbay.HTTP.Handler.FileJarServletLoader
*.*.Servlet.PROPERTY.AutoReloadDynamicServlets : True
*.*.Servlet.PROPERTY.SERVLET.*.Initialize : False
*.*.Servlet.PROPERTY.SERVLET.Dump.Initialize : True
*.*.Filter.PROPERTY.Html.CLASS : com.mortbay.HTTP.Filter.HtmlFilter

205
Modules/servlet/zzserv2.prp Normal file
View File

@@ -0,0 +1,205 @@
# ========================================================================
# Abbreviated Configuration file for com.mortbay.Jetty.Demo
#
# The format of this file is parsed by the com.mortbay.Util.PropertyTree
# class and interpreted by the com.mortbay.Jetty.Server class to
# construct, configure and start 1 or more HttpServer instances.
#
# This configuration file is abbrevited using the features of
# com.mortbay.Util.PropertyTree. It can be run with the command
# java com.mortbay.Jetty.Server etc/JettyMinimalDemo.prp
#
# A none abbreviated version of this configuration can be seen in
# JettyDemo.prp and associated files
# ------------------------------------------------------------------------
# ========================================================================
# Default CLASS definitions
# ------------------------------------------------------------------------
*.CLASS : com.mortbay.HTTP.HttpServer
*.LISTENER.*.CLASS : com.mortbay.HTTP.HttpListener
*.*.Log.CLASS : com.mortbay.HTTP.Handler.LogHandler
*.*.Auth.CLASS : com.mortbay.HTTP.Handler.BasicAuthHandler
*.*.Alias.CLASS : com.mortbay.HTTP.Handler.TranslateHandler
*.*.Filter.CLASS : com.mortbay.HTTP.Handler.FilterHandler
*.*.Html.CLASS : com.mortbay.HTTP.Filter.HtmlFilter
*.*.Param.CLASS : com.mortbay.HTTP.Handler.ParamHandler
*.*.Session.CLASS : com.mortbay.HTTP.Handler.SessionHandler
*.*.Servlet.CLASS : com.mortbay.HTTP.Handler.ServletHandler
*.*.File.CLASS : com.mortbay.HTTP.Handler.FileHandler
*.*.Forward.CLASS : com.mortbay.HTTP.Handler.ForwardHandler
*.*.NotFound.CLASS : com.mortbay.HTTP.Handler.NotFoundHandler
*.*.Proxy.CLASS : com.mortbay.HTTP.Handler.ProxyHandler
*.*.DefaultEx.CLASS : com.mortbay.HTTP.Handler.DefaultExceptionHandler
*.*.TerseEx.CLASS : com.mortbay.HTTP.Handler.TerseExceptionHandler
# ========================================================================
# Default Servlet CLASS definitions
# ------------------------------------------------------------------------
*.*.Servlet.PROPERTY.SERVLET.Dump.CLASS : com.mortbay.Servlets.Dump
*.*.Servlet.PROPERTY.SERVLET.Exit.CLASS : com.mortbay.Servlets.Exit
*.*.Servlet.PROPERTY.SERVLET.Session.CLASS : com.mortbay.Servlets.SessionDump
*.*.Servlet.PROPERTY.SERVLET.PropertyTree.CLASS: com.mortbay.Servlets.PropertyTreeEditor
*.*.Servlet.PROPERTY.SERVLET.Config.CLASS : com.mortbay.Servlets.ConfigDump
*.*.Servlet.PROPERTY.SERVLET.Debug.CLASS : com.mortbay.Servlets.DebugServlet
*.*.Servlet.PROPERTY.SERVLET.Laf.CLASS : com.mortbay.Servlets.LookAndFeelServlet
# ========================================================================
# Default ServletHandler Properties
# ------------------------------------------------------------------------
*.*.Servlet.PROPERTY.PATHS : /servlet/;/SERVLET/;/Servlet/
*.*.Servlet.PROPERTY.CLASSPATH : ./servlets
*.*.Servlet.PROPERTY.Loader : com.mortbay.HTTP.Handler.FileJarServletLoader
*.*.Servlet.PROPERTY.AutoReloadDynamicServlets : True
*.*.Servlet.PROPERTY.SERVLET.*.Initialize : False
*.*.Servlet.PROPERTY.SERVLET.Dump.Initialize : True
*.*.Filter.PROPERTY.Html.CLASS : com.mortbay.HTTP.Filter.HtmlFilter
# ========================================================================
# Default FileHandler Properties
# ------------------------------------------------------------------------
*.*.File.PROPERTY.AllowPut : False
*.*.File.PROPERTY.AllowDelete : False
*.*.File.PROPERTY.AllowDir : True
*.*.File.PROPERTY.Indexes : index.html;index.htm
*.*.File.PROPERTY.MaxCachedFiles : 100
*.*.File.PROPERTY.MaxCachedFileSize : 8192
# ========================================================================
# Define the server instances to be configured by this file:
# SERVERS - list if defined server names
# PROPERTY.* - Definition of global properties
# PROPERTIES - File of globl properties
# servername.* - PropertyTree describing server "servername".
#
# Defined global properties are:
# DefaultPageType - The class name of the default com.mortbay.HTML.Page
# type.
# ------------------------------------------------------------------------
SERVERS : main;proxy
PROPERTY.DefaultPageType : com.mortbay.Jetty.JettyLaF
# ========================================================================
# Define the server instance named "main"
# CLASS - The class name of the server. Must either be
# com.mortbay.HTTP.HttpServer or a decendant.
# LISTENER.name.CLASS - HttpListener classname or decendant
# LISTENER.name.ADDRS - List of addresses and ports to listen on
# STACKS - List of handler stack names.
# EXCEPTIONS - List of exception handler stack names.
# PROPERTY.* - Properties for this server
# PROPERTIES - File of properties for this server.
#
# Defined server properties are:
# SessionMaxInactiveInterval - Max idle time Ms before session death
# MinListenerThreads - Min listener threads per listener
# MaxListenerThreads - Max listener threads per listener
# MaxListenerThreadIdleMs - Max idle time Ms before listen thread
# death
# MimeMap - Property file of MIME mappings
#
# ------------------------------------------------------------------------
main.LISTENERS : all
main.LISTENER.all.ADDRS : 0.0.0.0:8080;127.0.0.1:8888
main.STACKS : root;files
main.EXCEPTIONS : defaultEx
main.PROPERTY.SessionMaxInactiveInterval : 3600
main.PROPERTY.MinListenerThreads : 3
main.PROPERTY.MaxListenerThreads : 20
main.PROPERTY.MaxListenerThreadIdleMs : 60000
# XXX
# main.PROPERTY.MimeMap : ./etc/Mime.prp
# ========================================================================
# Define the handler instances handler stack "root" in server "main"
# PATHS - List of PathMap path specifiactions for this stack
# HANDLERS - List of handler names for this stack.
# EXCEPTIONS - List of exception handler names for this stack.
# name.CLASS - The classname for the handler "name"
# name.PROPERTY.* - Properties defined for handler "name"
# name.PROPERTIES - file of properties defined for handler "name"
# ------------------------------------------------------------------------
main.root.PATHS : /
main.root.HANDLERS : Log;Auth;Alias;Filter;Param;Session;Servlet;File;Forward;NotFound
main.root.Log.PROPERTY.File : ./log/demo.log
main.root.Log.PROPERTY.Append : False
main.root.Log.PROPERTY.LongForm : True
main.root.Log.PROPERTY.CountContentLength : False
main.root.Log.PROPERTY.DateFormat : dd/MMM/yyyy:HH:mm:ss
# main.root.Auth.PROPERTIES : ./etc/JettyDemoRealms.prp
# main.root.Alias.PROPERTIES : ./etc/JettyDemoAlias.prp
main.root.Filter.PROPERTY.Html.PATHS : /
main.root.Param.PROPERTY.CookiesAsParameters : False
# ------------------------------------------------------------------------
main.root.Servlet.PROPERTY.SERVLET.Dump.PATHS : /Dump%;*.DUMP
main.root.Servlet.PROPERTY.SERVLET.Dump.CHUNK : True
main.root.Servlet.PROPERTY.SERVLET.Dump.PROPERTY.AttrX : ValueX
main.root.Servlet.PROPERTY.SERVLET.Dump.PROPERTY.AttrY : ValueY
main.root.Servlet.PROPERTY.SERVLET.Dump.PROPERTY.AttrZ : ValueZ
# main.root.Servlet.PROPERTY.SERVLET.Dump.PROPERTIES : ./etc/JettyDemoDump.prp
main.root.Servlet.PROPERTY.SERVLET.Exit.PATHS : /Exit
main.root.Servlet.PROPERTY.SERVLET.Session.PATHS : /SessionDump
main.root.Servlet.PROPERTY.SERVLET.PropertyTree.PATHS : /PropertyTree
main.root.Servlet.PROPERTY.SERVLET.Config.PATHS : /Config$
main.root.Servlet.PROPERTY.SERVLET.Debug.PATHS : /Debug$
main.root.Servlet.PROPERTY.SERVLET.Multi.PATHS : /Demo/push
main.root.Servlet.PROPERTY.SERVLET.Multi.CLASS : com.mortbay.Jetty.MultiPartCount
main.root.Servlet.PROPERTY.SERVLET.Gen.PATHS : /Demo/generate
main.root.Servlet.PROPERTY.SERVLET.Gen.CLASS : com.mortbay.Jetty.GenerateServlet
main.root.Servlet.PROPERTY.SERVLET.GenL.PATHS : /Demo/generateLaf
main.root.Servlet.PROPERTY.SERVLET.GenL.CLASS : com.mortbay.Jetty.GenerateLafServlet
main.root.Servlet.PROPERTY.SERVLET.Upload.PATHS : /Upload$
main.root.Servlet.PROPERTY.SERVLET.Upload.CLASS : com.mortbay.Jetty.UploadServlet
main.root.Servlet.PROPERTY.SERVLET.Laf.PATHS : /Jetty/Demo/;/Jetty/Info/;/Jetty/Config/;/Jetty/Program/
main.root.Servlet.PROPERTY.SERVLET.Laf.PROPERTY.ResourceBase: /laf
main.root.Servlet.PROPERTY.SERVLET.Index.PATHS : /Jetty|;/Jetty/Info|;/Jetty/Demo|;/Jetty/Program|;/Jetty/Config|
main.root.Servlet.PROPERTY.SERVLET.Index.CLASS : com.mortbay.Jetty.DemoIndex
# ------------------------------------------------------------------------
main.root.File.PROPERTY.FILES.FileBase.PATHS : /;/FileBase%
main.root.File.PROPERTY.FILES.FileBase.DIRECTORY : ./FileBase
# ------------------------------------------------------------------------
main.root.Forward.PROPERTY.FORWARD.demo.PATHS : /Forward%
main.root.Forward.PROPERTY.FORWARD.demo.URL : http://localhost:8080
main.root.Forward.PROPERTY.FORWARD.proxy.PATHS : http
main.root.Forward.PROPERTY.FORWARD.proxy.URL : http://localhost:8081
# ========================================================================
# Exception handler stacks 'default' and 'terse' for server 'main'
# HANDLERS - List of exception handler names for each stack.
# PATHS - List of PathMap path specifiactions for each stack
# name.CLASS - The classname for the handler "name"
# ------------------------------------------------------------------------
main.defaultEx.PATHS : /
main.defaultEx.HANDLERS : DefaultEx
main.defaultEx.DefaultEx.CLASS : com.mortbay.HTTP.Handler.DefaultExceptionHandler
# ========================================================================
# Define the handler stack "files" in server "main"
# ------------------------------------------------------------------------
main.files.HOSTS :
main.files.PATHS : /javadoc%;/laf%
main.files.HANDLERS : File;NotFound
main.files.File.PROPERTY.FILES.Laf.PATHS : /laf
main.files.File.PROPERTY.FILES.Laf.DIRECTORY : ./FileBase
main.files.File.PROPERTY.FILES.Javadoc.PATHS : /javadoc
main.files.File.PROPERTY.FILES.Javadoc.DIRECTORY : ./javadoc
main.files.File.PROPERTY.FILES.Servlet.PATHS : /javadoc/javax/servlet
main.files.File.PROPERTY.FILES.Servlet.DIRECTORY : ./src/javax/servlet/javadoc
# ========================================================================
# Define the server instance named "proxy"
# ------------------------------------------------------------------------
proxy.STACKS : root
proxy.LISTENER.all.ADDRS : 0.0.0.0:8081
# ========================================================================
# Define the handler stack "root" in server "proxy"
# ------------------------------------------------------------------------
proxy.root.HANDLERS : Log;Proxy;NotFound
proxy.root.PATHS : /
proxy.root.Log.PROPERTY.File : /tmp/demo.log
proxy.root.Log.PROPERTY.Append : True
proxy.root.Proxy.PROPERTY.PATHS : /;http;ftp

37
Modules/sound/Player.java Normal file
View File

@@ -0,0 +1,37 @@
/*
Player.java
*
* Copyright (c) 2001, Ted Nelson, Tuomas Lukka and Vesa Parkkinen
*
* 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 Vesa Parkkinen
*/
package org.gzigzag.module;
/** A (sound/video) player that doesn't need to know
* anything about zz.
*/
public interface Player {
// this needs more stuff, hashtable ?
// XXX getLength!!! -tjl
void init(String file);
void play(long from, long to, boolean loop);
void stop();
long getCurrentOffset();
}

View File

@@ -0,0 +1,37 @@
/*
Recorder.java
*
* Copyright (c) 2000, Ted Nelson, Tuomas Lukka and Vesa Parkkinen
*
* 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 Vesa Parkkinen
*/
package org.gzigzag.module;
public interface Recorder {
// what is needed in here ???
void init(String file, long offset);
void start();
void stop();
long getCurrentOffset();
}

View File

@@ -0,0 +1,65 @@
/*
SimplePlayer.java
*
* Copyright (c) 2001, Ted Nelson, Tuomas Lukka and Vesa Parkkinen
*
* 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 Vesa Parkkinen
*/
package org.gzigzag.module;
import org.gzigzag.*;
import java.util.*;
import java.io.*;
import java.net.*;
import java.awt.*;
/** A linux sound Player using GSM compression. Requires the associated native
* library.
*/
public class SimplePlayer implements Player {
private int handle;
public void init(String file){
handle = player_init(file);
}
public void play( long from, long to, boolean loop){
player_start(handle, from, to);
}
public void stop(){
player_stop(handle);
}
public long getCurrentOffset(){
return player_getCurrentOffset(handle);
}
static {
System.loadLibrary("recorder");
}
private native int player_init(String file);
private native void player_start(int handle, long from, long to);
private native long player_getCurrentOffset(int handle);
private native void player_stop(int handle );
}

View File

@@ -0,0 +1,68 @@
/*
SimpleRecorder.java
*
* Copyright (c) 2000, Ted Nelson, Tuomas Lukka and Vesa Parkkinen
*
* 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 Vesa Parkkinen
*/
package org.gzigzag.module;
import org.gzigzag.*;
import java.util.*;
import java.io.*;
import java.net.*;
import java.awt.*;
/**
* Simple (linux) native recorder class to be used in
* sound stream handling in zz.
*/
public class SimpleRecorder implements Recorder {
int handle = 0;
// inits recorder with a output file name
public void init(String file, long offset){
handle = recorder_init(file, offset);
}
public void start(){
recorder_start( handle );
}
public void stop(){
recorder_stop(handle);
}
public long getCurrentOffset(){
return recorder_getCurrentOffset(handle);
}
static {
System.loadLibrary("recorder");
}
private native void recorder_start(int handle);
private native void recorder_stop(int handle );
private native int recorder_init(String file, long offset);
private native long recorder_getCurrentOffset(int handle);
}

Some files were not shown because too many files have changed in this diff Show More