Files
gzz-mirror/Java/ZZWindows.java
2026-09-14 20:19:29 -04:00

232 lines
6.9 KiB
Java

/*
ZZWindows.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, killing by Antti-Juhani Kaijanaho,
* triggering and rootwin support by Rauli Ruohonen
*/
package org.gzigzag;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
public class ZZWindows {
public static final String rcsid = "$Id: ZZWindows.java,v 1.23 2001/01/03 16:47:50 raulir 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); }
/** Iff null, creates Frames at top level. */
private static Container rootwin;
private static ZZSpace rspace;
private static Hashtable views, frames, ex;
private static ZZObs obs = new ZZObs() { public void chg() { update(); }};
/** Must be called before anything else. */
public static void init(ZZSpace s,Container rootWin) {
rootwin=rootWin;
rspace=s;
if(views!=null) updateEnd();
views=new Hashtable();
frames=new Hashtable();
ex=new Hashtable();
ZZObsTrigger.chg(obs);
}
public static synchronized void update() {
p("update() start");
ZZCell rcell=startCell();
if(rcell==null) throw new ZZError("No 'Windows' cell found!");
ZZCell s=rcell.getOrNewCell("d.1",1,obs);
if(rootwin!=null) updateRoot(s);
else updateFrames(s);
updateEnd();
p("update() end");
}
// XXX Should create a ZZWindow class for operating on the structure?
public static Rectangle getBounds(ZZCell c, ZZObs obs) {
try {
int[] a=ZZUtil.getInts(c.s("d.1",-1),"d.bounds",false,4,4,obs);
return new Rectangle(a[0], a[1], a[2], a[3]);
} catch(ZZError e) {
return null;
}
}
public static Rectangle getBounds(ZZCell c) { return getBounds(c,null); }
public static void setBounds(ZZCell c, Rectangle r) {
Rectangle b=getBounds(c);
if(b!=null&&b.equals(r)) return;
ZZUtil.putInts(c.s("d.1",-1), "d.bounds", false,
new int[] { r.x, r.y, r.width, r.height });
}
public static ZZCell startCell() {
return ZZDefaultSpace.findOnClientlist(rspace, "Windows", false);
}
public static synchronized ZZViewComponent getContent(ZZCell c) {
String txt = c.getText(obs);
if(txt.equals("Canvas")) {
ZZCanvasView v;
if(views.get(c) instanceof ZZCanvasView)
v = (ZZCanvasView) views.get(c);
else
views.put(c, v = new ZZCanvasView());
ZZCell vcell = c.s("d.1", 1,obs);
if(vcell == null) return null;
v.setViewcell(vcell);
return v;
}
return null;
}
private static void updateRoot(ZZCell s) {
ScalableFont.fmComp=rootwin;
updateWindowAttributes(s,rootwin);
updatePanels(s.s("d.2",1,obs),rootwin);
rootwin.validate();
}
private static void updateFrames(ZZCell s) {
s=s.s("d.2",1,obs);
while(s!=null) {
boolean created=false;
ZZCell c=s.s("d.1",1,obs);
if(c!=null) {
Frame f=(Frame)frames.get(c);
if(f==null) {
created=true;
frames.put(c,f=new Frame());
initWindow(c,f);
final ZZCell cell=c;
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
p("windowClosing()");
ZZUpdateManager.freeze();
try {
cell.s("d.1",-1).excise("d.2");
ZZObsTrigger.runObsQueue();
} finally { ZZUpdateManager.thaw(); }
}
});
}
ScalableFont.fmComp=f;
ex.put(c,c);
Rectangle r=getBounds(c,obs);
if(r!=null&&!f.getBounds().equals(r)) f.setBounds(r);
f.setTitle(s.getText(obs));
p("Frame name: "+f.getTitle());
Container cont=getContent(c);
if(cont!=null) {
updateWindowAttributes(s,cont);
cont.removeAll(); // FIXME
updatePanels(c.s("d.2",1,obs),cont);
if(f.getComponentCount()!=1||f.getComponent(0)!=cont) {
p("Changing frame component and validating.");
f.removeAll();
f.add(cont);
f.validate();
}
}
if(created) f.setVisible(true);
}
s=s.s("d.2",1,obs);
}
}
private static void updatePanels(ZZCell s,Container parent) {
if(s==null) return;
// FIXME This kludge is here so that applets still work. The real
// functionality should be here Real Soon Now(TM). (Yeah, *right*)
parent.removeAll();
Container cont=getContent(s.s("d.1",1,obs));
updateWindowAttributes(s,cont);
parent.add(cont);
}
private static void initWindow(final ZZCell c,final Container w) {
w.addComponentListener(new ComponentAdapter() {
public void componentMoved(ComponentEvent e) {
ZZUpdateManager.freeze();
try {
ZZObsTrigger.setEnabled(obs,false);
setBounds(c, w.getBounds());
ZZObsTrigger.setEnabled(obs,true);
ZZObsTrigger.runObsQueue();
} finally { ZZUpdateManager.thaw(); }
}
public void componentResized(ComponentEvent e) {
ZZUpdateManager.freeze();
try {
ZZObsTrigger.setEnabled(obs,false);
setBounds(c, w.getBounds());
ZZObsTrigger.setEnabled(obs,true);
ZZObsTrigger.runObsQueue();
} finally { ZZUpdateManager.thaw(); }
}
});
}
private static void updateWindowAttributes(ZZCell c,Container w) {
ZZCell col=c.s("d.color",1,obs);
if(col!=null) {
String colText = col.getText(obs);
// See if it looks like an URL or a number.
if(Character.isDigit(colText.charAt(0)) ||
colText.charAt(0) == '-')
w.setBackground( Color.decode(colText) );
else {
ZZLogger.log("Not digit first! '"+colText+"'");
// XXX Find image, store it in the right place (should be
// in content...
/*
URL url = null;
try {
url = new URL(cursor.h("d.photo", 1).getText());
} catch(MalformedURLException e) {
String s= e.toString();
g.drawString(s, 0, 0);
return;
}
if(!url.equals(cur)) {
cur = url;
img = getToolkit().getImage(url);
}
if(!g.drawImage(img, 0, 0, null)) {
repaint(1000);
}
*/
}
if((col=col.s("d.color", 1,obs)) != null)
w.setForeground( Color.decode(col.getText(obs)) );
}
}
private static void updateEnd() {
for (Enumeration e = views.keys(); e.hasMoreElements();) {
ZZCell cell = (ZZCell) e.nextElement();
if(!ex.containsKey(cell)) views.remove(cell);
}
for (Enumeration e = frames.keys(); e.hasMoreElements();) {
ZZCell cell = (ZZCell) e.nextElement();
if(ex.containsKey(cell)) continue;
Frame f = (Frame)frames.get(cell);
f.dispose();
frames.remove(cell);
}
ex=new Hashtable();
}
}