samer@0
|
1 /*
|
samer@0
|
2 * Copyright (c) 2000, Samer Abdallah, King's College London.
|
samer@0
|
3 * All rights reserved.
|
samer@0
|
4 *
|
samer@0
|
5 * This software is provided AS iS and WITHOUT ANY WARRANTY;
|
samer@0
|
6 * without even the implied warranty of MERCHANTABILITY or
|
samer@0
|
7 * FITNESS FOR A PARTICULAR PURPOSE.
|
samer@0
|
8 */
|
samer@0
|
9
|
samer@0
|
10 package samer.core.util;
|
samer@0
|
11
|
samer@0
|
12 import samer.core.*;
|
samer@0
|
13 import samer.core.types.*;
|
samer@0
|
14 import java.util.*;
|
samer@0
|
15 import java.awt.*;
|
samer@0
|
16
|
samer@0
|
17 /**
|
samer@0
|
18 An Agent and Viewable that manages a IMap object - provides
|
samer@0
|
19 a user interface for adjusting the domain.
|
samer@0
|
20 */
|
samer@0
|
21
|
samer@0
|
22 public class VMap extends Viewable implements Agent
|
samer@0
|
23 {
|
samer@0
|
24 IMap map;
|
samer@0
|
25 boolean symmetric;
|
samer@0
|
26
|
samer@0
|
27 public static final Object NEW_MAP = new Object();
|
samer@0
|
28
|
samer@0
|
29 public VMap(IMap m) { this(m,true); }
|
samer@0
|
30 public VMap(IMap m, Node node) { this(m,true,node); }
|
samer@0
|
31 public VMap(IMap m, boolean init) { this(m,init,new Node("map")); }
|
samer@0
|
32
|
samer@0
|
33 /** Construct a VMap from a given IMap and node. The boolean init flag specifies
|
samer@0
|
34 whether or not the VMap should reinitialise the IMap from the current Environment
|
samer@0
|
35 */
|
samer@0
|
36
|
samer@0
|
37 public VMap(IMap m, boolean init, Node node)
|
samer@0
|
38 {
|
samer@0
|
39 super(node);
|
samer@0
|
40 setAgent(this);
|
samer@0
|
41
|
samer@0
|
42 map = m;
|
samer@0
|
43 symmetric = false;
|
samer@0
|
44
|
samer@0
|
45 if (init) {
|
samer@0
|
46 Shell.push(getNode());
|
samer@0
|
47 try {
|
samer@0
|
48 boolean logmap = Shell.getBoolean("log", false);
|
samer@0
|
49
|
samer@0
|
50 if (logmap) { map=new LogMap(); symmetric=false; }
|
samer@0
|
51 else symmetric = Shell.getBoolean( "symmetric", symmetric);
|
samer@0
|
52
|
samer@0
|
53 setDomain(
|
samer@0
|
54 Shell.getDouble("minimum",map.getDomainMin()),
|
samer@0
|
55 Shell.getDouble("maximum",map.getDomainMax())
|
samer@0
|
56 );
|
samer@0
|
57 } finally { Shell.pop(); }
|
samer@0
|
58 }
|
samer@0
|
59 }
|
samer@0
|
60
|
samer@0
|
61 public void setMap( IMap m) { map=m; changed(NEW_MAP); }
|
samer@0
|
62 public IMap getMap() { return map; }
|
samer@0
|
63
|
samer@0
|
64 public String toString() { return super.toString()+"="+map.toString(); }
|
samer@0
|
65
|
samer@0
|
66 // ........... Viewable bits ................
|
samer@0
|
67
|
samer@0
|
68 public void dispose()
|
samer@0
|
69 {
|
samer@0
|
70 Shell.deregisterAgent(this);
|
samer@0
|
71 super.dispose();
|
samer@0
|
72 }
|
samer@0
|
73
|
samer@0
|
74 public Viewer getViewer() { return new Adjuster(); }
|
samer@0
|
75
|
samer@0
|
76 // ........... Agent Bits ...................
|
samer@0
|
77
|
samer@0
|
78 public void getCommands(Agent.Registry r) {
|
samer@0
|
79 r.add("domain").add("symmetric",symmetric);
|
samer@0
|
80 r.add("linear").add("log");
|
samer@0
|
81 r.group();
|
samer@0
|
82 r.add("put").add("get");
|
samer@0
|
83 }
|
samer@0
|
84
|
samer@0
|
85 public void execute(String c, Environment env) throws Exception
|
samer@0
|
86 {
|
samer@0
|
87 if (c.equals("domain")) {
|
samer@0
|
88 Shell.showDialogFor(getViewer().getComponent(),Node.lastPart(node.fullName()));
|
samer@0
|
89 } else if (c.equals("symmetric")) {
|
samer@0
|
90 symmetric = X._bool(env.datum(),!symmetric);
|
samer@0
|
91 setDomain( map.getDomainMin(), map.getDomainMax());
|
samer@0
|
92 changed();
|
samer@0
|
93 } else if (c.equals("linear")) {
|
samer@0
|
94 IMap newmap = new LinearMap( );
|
samer@0
|
95 newmap.setDomain( map.getDomainMin(), map.getDomainMax());
|
samer@0
|
96 newmap.setIntRange( map.getIntRange());
|
samer@0
|
97 setMap(newmap);
|
samer@0
|
98 } else if (c.equals("log")) {
|
samer@0
|
99 double min=map.getDomainMin();
|
samer@0
|
100 double max=map.getDomainMax();
|
samer@0
|
101
|
samer@0
|
102 if (min<=0) min=max/1000; // default dynamic range
|
samer@0
|
103 symmetric=false;
|
samer@0
|
104 setMap(new LogMap(min,max,map.getIntRange()));
|
samer@0
|
105 } else if (c.equals("put")) Shell.put("map",this);
|
samer@0
|
106 else if (c.equals("get")) setMap(((VMap)Shell.get("map")).getMap().copy());
|
samer@0
|
107 /* or
|
samer@0
|
108 } else if (c.equals("put")) Shell.put("map",this.getMap().copy());
|
samer@0
|
109 else if (c.equals("get")) setMap((IMap)Shell.get("map"));
|
samer@0
|
110 */
|
samer@0
|
111 }
|
samer@0
|
112
|
samer@0
|
113 public void setSymmetric(boolean f) { symmetric=f; }
|
samer@0
|
114 public void setDomain( double min, double max)
|
samer@0
|
115 {
|
samer@0
|
116 if (map instanceof LogMap) {
|
samer@0
|
117 if (min<=0) min=max/1000;
|
samer@0
|
118 } else {
|
samer@0
|
119 if (symmetric) { max=Math.max(max,-min); min=-max; }
|
samer@0
|
120 }
|
samer@0
|
121 // Shell.trace("new domain=["+min+","+max+")");
|
samer@0
|
122 map.setDomain(min,max);
|
samer@0
|
123 }
|
samer@0
|
124
|
samer@0
|
125 class Adjuster extends BaseViewer
|
samer@0
|
126 {
|
samer@0
|
127 VBoolean sym;
|
samer@0
|
128 VDouble t1, t2;
|
samer@0
|
129
|
samer@0
|
130 Adjuster()
|
samer@0
|
131 {
|
samer@0
|
132 super(VMap.this);
|
samer@0
|
133 panel().setName(getLabel());
|
samer@0
|
134 Shell.push(getNode());
|
samer@0
|
135
|
samer@0
|
136 setLayout( new StackLayout());
|
samer@0
|
137
|
samer@0
|
138 t1 = new VDouble("maximum",map.getDomainMax(),Variable.NOINIT);
|
samer@0
|
139 t2 = new VDouble("minimum",map.getDomainMin(),Variable.NOINIT);
|
samer@0
|
140 sym= new VBoolean("symmetric",symmetric,Variable.NOINIT);
|
samer@0
|
141 t1.addObserver(this);
|
samer@0
|
142 t2.addObserver(this);
|
samer@0
|
143 sym.addObserver(this);
|
samer@0
|
144
|
samer@0
|
145 add(t1.getViewer().getComponent());
|
samer@0
|
146 add(t2.getViewer().getComponent());
|
samer@0
|
147 add(sym.getViewer().getComponent());
|
samer@0
|
148
|
samer@0
|
149 Shell.pop();
|
samer@0
|
150 }
|
samer@0
|
151
|
samer@0
|
152 public void update(Observable o, Object src)
|
samer@0
|
153 {
|
samer@0
|
154 if (src==this) return; // &&&
|
samer@0
|
155 if (VMap.this.equals(o)) {
|
samer@0
|
156 // means someone has changed the map ...
|
samer@0
|
157 // ... and if it wasn't us...
|
samer@0
|
158 t1.value=map.getDomainMax(); t1.changed(this);
|
samer@0
|
159 t2.value=map.getDomainMin(); t2.changed(this);
|
samer@0
|
160 if (sym.value!=symmetric) {
|
samer@0
|
161 sym.value=symmetric; sym.changed(this);
|
samer@0
|
162 }
|
samer@0
|
163 } else {
|
samer@0
|
164 // Widget adjusted
|
samer@0
|
165 // user has adjusted controls...
|
samer@0
|
166 // must set map and notify any observers
|
samer@0
|
167 if (sym==o) {
|
samer@0
|
168 if (symmetric=sym.value) {
|
samer@0
|
169 double max=Math.max(t1.value,-t2.value);
|
samer@0
|
170 t1.value=max; t2.value=-max;
|
samer@0
|
171 t1.changed(this); t2.changed(this);
|
samer@0
|
172 }
|
samer@0
|
173 } else {
|
samer@0
|
174 if (symmetric) {
|
samer@0
|
175 if (t1==o) { t2.value=-t1.value; t2.changed(this); }
|
samer@0
|
176 else if (t2==o) { t1.value=-t2.value; t1.changed(this); }
|
samer@0
|
177 }
|
samer@0
|
178 }
|
samer@0
|
179 map.setDomain(t2.value,t1.value);
|
samer@0
|
180 changed(this);
|
samer@0
|
181 // else, WE adjusted the controls to
|
samer@0
|
182 // reflect reality, so do nothing
|
samer@0
|
183 }
|
samer@0
|
184 }
|
samer@0
|
185 }
|
samer@0
|
186 }
|
samer@0
|
187
|
samer@0
|
188
|