diff src/samer/core_/util/VMap.java @ 0:bf79fb79ee13

Initial Mercurial check in.
author samer
date Tue, 17 Jan 2012 17:50:20 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/samer/core_/util/VMap.java	Tue Jan 17 17:50:20 2012 +0000
@@ -0,0 +1,188 @@
+/*
+ *	Copyright (c) 2000, Samer Abdallah, King's College London.
+ *	All rights reserved.
+ *
+ *	This software is provided AS iS and WITHOUT ANY WARRANTY;
+ *	without even the implied warranty of MERCHANTABILITY or
+ *	FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+package	samer.core.util;
+
+import   samer.core.*;
+import	samer.core.types.*;
+import	java.util.*;
+import	java.awt.*;
+
+/**
+	An Agent and Viewable that manages a IMap object - provides
+	a user interface for adjusting the domain.
+ */
+
+public class VMap extends Viewable implements Agent
+{
+	IMap		map;
+	boolean	symmetric;
+
+	public static final Object NEW_MAP = new Object();
+
+	public VMap(IMap m) { this(m,true); }
+	public VMap(IMap m, Node node) { this(m,true,node); }
+	public VMap(IMap m, boolean init) { this(m,init,new Node("map")); }
+
+	/** Construct a VMap from a given IMap and node. The boolean init flag specifies
+		whether or not the VMap should reinitialise the IMap from the current Environment
+	*/
+	
+	public VMap(IMap m, boolean init, Node node)
+	{
+		super(node);
+		setAgent(this);
+
+		map = m;
+		symmetric = false;
+
+		if (init) {
+			Shell.push(getNode());
+			try {
+				boolean logmap = Shell.getBoolean("log", false);
+
+				if (logmap) { map=new LogMap(); symmetric=false; }
+				else symmetric = Shell.getBoolean( "symmetric", symmetric);
+
+				setDomain(
+					Shell.getDouble("minimum",map.getDomainMin()),
+					Shell.getDouble("maximum",map.getDomainMax())
+				);
+			} finally { Shell.pop(); }
+		}
+	}
+
+	public void setMap( IMap m) { map=m; changed(NEW_MAP); }
+	public IMap getMap() { return map; }
+
+	public String toString() { return super.toString()+"="+map.toString(); }
+	
+	// ........... Viewable bits ................
+
+	public void dispose()
+	{
+		Shell.deregisterAgent(this);
+		super.dispose();
+	}
+
+	public Viewer	getViewer() { return new Adjuster(); }
+
+	// ........... Agent Bits ...................
+
+	public void getCommands(Agent.Registry r) {
+		r.add("domain").add("symmetric",symmetric);
+		r.add("linear").add("log");
+		r.group();
+		r.add("put").add("get");
+	}
+
+	public void execute(String c, Environment env) throws Exception
+	{
+		if (c.equals("domain"))	{
+			Shell.showDialogFor(getViewer().getComponent(),Node.lastPart(node.fullName()));
+		} else if (c.equals("symmetric")) {
+			symmetric = X._bool(env.datum(),!symmetric);
+			setDomain( map.getDomainMin(), map.getDomainMax());
+			changed();
+		} else if (c.equals("linear")) {
+			IMap newmap = new LinearMap( );
+			newmap.setDomain( map.getDomainMin(), map.getDomainMax());
+			newmap.setIntRange( map.getIntRange());
+			setMap(newmap);
+		} else if (c.equals("log")) {
+			double min=map.getDomainMin();
+			double max=map.getDomainMax();
+
+			if (min<=0) min=max/1000; // default dynamic range
+			symmetric=false;
+			setMap(new LogMap(min,max,map.getIntRange()));
+		} else if (c.equals("put")) Shell.put("map",this);
+		else if (c.equals("get")) setMap(((VMap)Shell.get("map")).getMap().copy());
+		/* or
+			} else if (c.equals("put")) Shell.put("map",this.getMap().copy());
+			else if (c.equals("get")) setMap((IMap)Shell.get("map"));
+		*/
+	}
+
+	public void setSymmetric(boolean f) { symmetric=f; }
+	public void setDomain( double min, double max)
+	{
+		if (map instanceof LogMap) {
+			if (min<=0) min=max/1000;
+		} else {
+			if (symmetric) { max=Math.max(max,-min); min=-max; }
+		}
+		// Shell.trace("new domain=["+min+","+max+")");
+		map.setDomain(min,max);
+	}
+
+	class Adjuster extends BaseViewer
+	{
+		VBoolean		sym;
+		VDouble		t1, t2;
+
+		Adjuster()
+		{
+			super(VMap.this);
+			panel().setName(getLabel());
+			Shell.push(getNode());
+
+			setLayout( new StackLayout());
+
+			t1 = new VDouble("maximum",map.getDomainMax(),Variable.NOINIT);
+			t2 = new VDouble("minimum",map.getDomainMin(),Variable.NOINIT);
+			sym= new VBoolean("symmetric",symmetric,Variable.NOINIT);
+			t1.addObserver(this);
+			t2.addObserver(this);
+			sym.addObserver(this);
+
+			add(t1.getViewer().getComponent());
+			add(t2.getViewer().getComponent());
+			add(sym.getViewer().getComponent());
+
+			Shell.pop();
+		}
+
+		public void update(Observable o, Object src)
+		{
+			if (src==this) return; // &&&
+			if (VMap.this.equals(o)) {
+				// means someone has changed the map ...
+				// ... and if it wasn't us...
+				t1.value=map.getDomainMax(); t1.changed(this);
+				t2.value=map.getDomainMin(); t2.changed(this);
+				if (sym.value!=symmetric) {
+					sym.value=symmetric; sym.changed(this);
+				}
+			} else {
+				// Widget adjusted
+				// user has adjusted controls...
+				// must set map and notify any observers
+				if (sym==o) {
+					if (symmetric=sym.value) {
+						double max=Math.max(t1.value,-t2.value);
+						t1.value=max; t2.value=-max;
+						t1.changed(this); t2.changed(this);
+					}
+				} else {
+					if (symmetric) {
+						if (t1==o)      { t2.value=-t1.value; t2.changed(this); }
+						else if (t2==o) {	t1.value=-t2.value; t1.changed(this); }
+					}
+				}
+				map.setDomain(t2.value,t1.value);
+				changed(this);
+				// else, WE adjusted the controls to
+				// reflect reality, so do nothing
+			}
+		}
+	}
+}
+
+