2 classvar <allInspectors;
4 var <object, <window, vpos=0, gui;
8 inspector = this.inspectorFor(object) ?? {
9 super.newCopyArgs(object).init;
11 inspector.window.front;
14 *initClass { allInspectors = []; }
15 *inspectorFor { arg object;
16 ^allInspectors.detect({ arg item;
17 item.object === object
21 allInspectors = allInspectors.add(this);
31 allInspectors.remove(this);
34 buttonHeight { ^this.lineHeight - 4 }
37 bounds = Rect(80, 80, 376, this.lineHeight * (this.numLines + 1) + 16);
39 window = gui.window.new(object.class.name.asString ++ " inspector", bounds);
40 window.onClose = Message(this, \didClose);
48 ObjectInspector : Inspector {
50 var stringView, slotInspectors;
53 ^min(30, object.slotSize); // don't display too many lines
58 view = gui.button.new(window, Rect(8, vpos, 128, this.buttonHeight));
59 view.states = [[object.class.name]];
60 view.action = { GUI.use( gui, { object.class.inspect })};
63 view = gui.button.new(window, Rect(140, vpos, 50, this.buttonHeight));
64 view.states = [["update"]];
65 view.action = Message(this, \update);
68 view = gui.dragSource.new(window, Rect(194, vpos, 174, this.buttonHeight));
73 vpos = vpos + this.lineHeight;
77 this.numLines.do({ arg i;
78 slotInspectors = slotInspectors.add(
79 SlotInspector(this, i, vpos)
81 vpos = vpos + this.lineHeight;
83 // ... link to rest, or scroll view
87 stringView.object = object;
88 slotInspectors.do({ arg slotinsp;
94 StringInspector : ObjectInspector {
95 // don't bother with the array of Chars.
99 ClassInspector : ObjectInspector {
102 view = gui.button.new(window, Rect(8, vpos, 128, this.buttonHeight));
103 view.states = [[object.class.name]];
104 view.action = { GUI.use( gui, { object.class.inspect })};
106 view = gui.button.new(window, Rect(140, vpos, 50, this.buttonHeight));
107 view.states = [["edit"]];
108 view.action = Message(object, \openCodeFile);
110 if (object.superclass.notNil, {
111 view = gui.button.new(window, Rect(194, vpos, 70, this.buttonHeight));
112 view.states = [["superclass"]];
113 view.action = { GUI.use( gui, { object.superclass.inspect })};
116 view = gui.dragSource.new(window, Rect(268, vpos, 96, this.buttonHeight));
117 view.object = object;
121 vpos = vpos + this.lineHeight;
126 FunctionDefInspector : ObjectInspector {
128 GUI.use( gui, { object.superclass.inspect });
132 view = gui.button.new(window, Rect(8, vpos, 128, this.buttonHeight));
133 view.states = [[object.class.name]];
134 view.action = { GUI.use( gui, { object.class.inspect })};
136 if (object.code.notNil, {
137 view = gui.button.new(window, Rect(194, vpos, 70, this.buttonHeight));
138 view.states = [["dump code"]];
139 view.action = Message(object, \dumpByteCodes);
142 view = gui.dragSource.new(window, Rect(268, vpos, 96, this.buttonHeight));
143 view.object = object;
147 vpos = vpos + this.lineHeight;
151 MethodInspector : ObjectInspector {
153 GUI.use( gui, { object.superclass.inspect });
157 view = gui.button.new(window, Rect(8, vpos, 128, this.buttonHeight));
158 view.states = [[object.class.name]];
159 view.action = { GUI.use( gui, { object.class.inspect })};
161 view = gui.button.new(window, Rect(140, vpos, 50, this.buttonHeight));
162 view.states = [["edit"]];
163 view.action = Message(object, \openCodeFile);
165 if (object.code.notNil, {
166 view = gui.button.new(window, Rect(194, vpos, 70, this.buttonHeight));
167 view.states = [["dump code"]];
168 view.action = Message(object, \dumpByteCodes);
171 view = gui.dragSource.new(window, Rect(268, vpos, 96, this.buttonHeight));
172 view.object = object;
176 vpos = vpos + this.lineHeight;
181 var <object, <>index, <key, <slotKeyView, <slotValueView, <inspectButton;
185 *new { arg inspector, index, vpos;
186 ^super.newCopyArgs(inspector.object, index).init(inspector, vpos)
188 init { arg inspector, vpos;
189 var w, class, hasGetter, hasSetter, vbounds, value;
193 w = inspector.window;
194 key = object.slotKey(index);
195 class = object.class;
197 slotKeyView = gui.staticText.new(w, Rect(8, vpos, 110, this.buttonHeight));
198 slotKeyView.align = \right;
199 // slotKeyView.font = gui.font.default ?? { gui.font.new("Helvetica", 12) };
201 if (key.isKindOf(Symbol), {
202 hasGetter = class.findRespondingMethodFor(key).notNil;
203 hasSetter = class.findRespondingMethodFor(key.asSetter).notNil && object.mutable;
206 hasSetter = object.mutable;
208 //slotKeyView.background = Color.grey(if(hasGetter,0.95,0.85));
210 vbounds = Rect(122, vpos, 218, this.buttonHeight);
213 slotValueView = gui.dragBoth.new(w, vbounds);
215 slotValueView = gui.dragSink.new(w, vbounds);
217 slotValueView.action = Message(this, \setSlot);
220 slotValueView = gui.dragSource.new(w, vbounds);
222 slotValueView = gui.staticText.new(w, vbounds);
225 slotValueView.resize = 2;
226 // slotValueView.font = gui.font.default ?? { gui.font.new("Helvetica", 12) };
227 //slotValueView.background = Color.grey(if(hasSetter,0.95,0.85));
229 inspectButton = gui.button.new(w, Rect(344, vpos, this.buttonHeight, this.buttonHeight));
230 inspectButton.states = [["I"]];
231 inspectButton.action = Message(this, \inspectSlot);
232 inspectButton.resize = 3;
233 //inspectButton.visible = true; //object.slotAt(index).canInspect;
237 key = object.slotKey(index);
238 slotKeyView.string = key;
239 slotValueView.object = object.slotAt(index);
240 //inspectButton.visible = true; //object.slotAt(index).canInspect;
243 GUI.use( gui, { object.slotAt(index).inspect });
246 if (key.isKindOf(Symbol), {
247 object.perform(key.asSetter, gui.view.currentDrag);
249 object.put(key, gui.view.currentDrag);
254 buttonHeight { ^this.lineHeight - 4 }
257 FrameInspector : Inspector {
262 view = gui.button.new(window, Rect(8, vpos, 128, this.buttonHeight));
263 view.states = [[object.class.name]];
264 view.action = { GUI.use( gui, { object.class.inspect })};
266 vpos = vpos + this.lineHeight;