15
15
*/
16
16
package org .tros .torgo ;
17
17
18
+ import bibliothek .gui .dock .DefaultDockable ;
19
+ import bibliothek .gui .dock .common .CControl ;
20
+ import bibliothek .gui .dock .common .CGrid ;
21
+ import bibliothek .gui .dock .common .CLocation ;
22
+ import bibliothek .gui .dock .common .DefaultSingleCDockable ;
23
+ import bibliothek .gui .dock .common .mode .ExtendedMode ;
24
+ import bibliothek .gui .dock .common .SingleCDockable ;
25
+ import bibliothek .gui .dock .common .SingleCDockableFactory ;
26
+ import bibliothek .util .xml .XElement ;
27
+ import bibliothek .util .xml .XIO ;
18
28
import org .tros .torgo .interpreter .CodeBlock ;
19
29
import org .tros .torgo .interpreter .InterpreterListener ;
20
30
import org .tros .torgo .interpreter .InterpreterThread ;
21
31
import org .tros .torgo .interpreter .Scope ;
22
32
import java .awt .BorderLayout ;
33
+ import java .awt .Component ;
23
34
import java .awt .Container ;
24
35
import java .awt .Desktop ;
25
36
import java .awt .event .ActionEvent ;
26
37
import java .awt .event .ActionListener ;
27
38
import java .awt .event .WindowEvent ;
28
39
import java .awt .event .WindowListener ;
29
- import java .beans .PropertyChangeEvent ;
30
- import java .beans .PropertyChangeListener ;
31
40
import java .io .File ;
41
+ import java .io .FileInputStream ;
42
+ import java .io .FileNotFoundException ;
32
43
import java .io .FileOutputStream ;
33
44
import java .io .IOException ;
34
45
import java .io .StringWriter ;
48
59
import javax .swing .JMenuBar ;
49
60
import javax .swing .JMenuItem ;
50
61
import javax .swing .JOptionPane ;
51
- import javax .swing .JSplitPane ;
52
62
import javax .swing .JToolBar ;
53
63
import javax .swing .SwingUtilities ;
54
64
import org .apache .commons .io .IOUtils ;
55
65
import org .apache .commons .lang3 .event .EventListenerSupport ;
66
+ import org .apache .commons .lang3 .tuple .ImmutablePair ;
56
67
import static org .tros .torgo .Main .IMAGE_ICON_CLASS_PATH ;
57
68
import org .tros .torgo .swing .AboutWindow ;
58
69
import org .tros .torgo .swing .Localization ;
59
70
import org .tros .torgo .swing .TorgoMenuBar ;
60
71
import org .tros .utils .swing .NamedWindow ;
61
72
import org .tros .utils .AutoResetEvent ;
73
+ import org .tros .utils .PathUtils ;
62
74
63
75
/**
64
76
* The main application. Controls GUI and interpreting process.
@@ -74,6 +86,7 @@ public abstract class ControllerBase implements Controller {
74
86
private String filename ;
75
87
protected final AutoResetEvent step ;
76
88
protected final AtomicBoolean isStepping ;
89
+ private CControl dockControl ;
77
90
78
91
private final ArrayList <JCheckBoxMenuItem > viz = new ArrayList <>();
79
92
@@ -157,6 +170,55 @@ protected ControllerBase() {
157
170
*/
158
171
protected abstract InterpreterThread createInterpreterThread (String source );
159
172
173
+ public static class TorgoSingleDockable extends DefaultSingleCDockable {
174
+
175
+ public TorgoSingleDockable (String title , final Component panel ) {
176
+ super (title );
177
+ super .setTitleText (title );
178
+ super .add (panel );
179
+ }
180
+ }
181
+
182
+ public static class TorgoDockable extends DefaultDockable {
183
+
184
+ public TorgoDockable (String title , final Component panel ) {
185
+ super (title );
186
+ super .setTitleText (title );
187
+ super .add (panel );
188
+ }
189
+ }
190
+
191
+ /* This method simulates the creation of a layout */
192
+ private static XElement createLayout (Component display , ArrayList <ImmutablePair <String , Component >> input ) {
193
+ /* This method simulates the creation of a layout */
194
+ CControl control = new CControl ();
195
+ control .getContentArea ();
196
+
197
+ CGrid grid = new CGrid (control );
198
+
199
+ DefaultSingleCDockable displayDock = display != null ? new TorgoSingleDockable ("Display" , display ) : null ;
200
+ if (displayDock != null ) {
201
+ grid .add (0 , 0 , 10 , 10 , displayDock );
202
+ displayDock .setLocation (CLocation .base ().minimalWest ());
203
+ displayDock .setExtendedMode (ExtendedMode .NORMALIZED );
204
+ }
205
+
206
+ int count = 1 ;
207
+ for (ImmutablePair <String , Component > key : input ) {
208
+ DefaultSingleCDockable dock = new TorgoSingleDockable (key .left , key .right );
209
+ grid .add (10 , 0 , 6 , count , dock );
210
+ dock .setExtendedMode (ExtendedMode .NORMALIZED );
211
+ count += 1 ;
212
+ }
213
+
214
+ control .getContentArea ().deploy (grid );
215
+
216
+ XElement root = new XElement ("root" );
217
+ control .writeXML (root );
218
+ control .destroy ();
219
+ return root ;
220
+ }
221
+
160
222
/**
161
223
* Initialize the window. This is called here from run() and not the
162
224
* constructor so that the Service Provider doesn't load up all of the
@@ -173,22 +235,72 @@ private void initSwing() {
173
235
contentPane .add (tb , BorderLayout .NORTH );
174
236
}
175
237
176
- final java .util .prefs .Preferences prefs = java .util .prefs .Preferences .userNodeForPackage (NamedWindow .class );
238
+ dockControl = new CControl (window );
239
+ window .add (dockControl .getContentArea (), BorderLayout .CENTER );
240
+ final ArrayList <String > presetFilter = new ArrayList <>();
177
241
if (torgoCanvas != null ) {
178
- final JSplitPane splitPane = new JSplitPane (JSplitPane .HORIZONTAL_SPLIT , torgoCanvas .getComponent (), torgoPanel .getComponent ());
179
- int dividerLocation = prefs .getInt (this .getClass ().getName () + "divider-location" , window .getWidth () - 300 );
180
- splitPane .setDividerLocation (dividerLocation );
181
- splitPane .addPropertyChangeListener (new PropertyChangeListener () {
182
-
183
- @ Override
184
- public void propertyChange (PropertyChangeEvent pce ) {
185
- prefs .putInt (this .getClass ().getName () + "divider-location" , splitPane .getDividerLocation ());
242
+ presetFilter .add ("Display" );
243
+ }
244
+ for (ImmutablePair <String , Component > pair : torgoPanel .getTorgoComponents ()) {
245
+ presetFilter .add (pair .left );
246
+ }
247
+ bibliothek .util .Filter <String > filter = new bibliothek .util .Filter <String >() {
248
+ @ Override
249
+ public boolean includes (String item ) {
250
+ return presetFilter .contains (item );
251
+ }
252
+ };
253
+ dockControl .addSingleDockableFactory (filter , new SingleCDockableFactory () {
254
+ @ Override
255
+ public SingleCDockable createBackup (String id ) {
256
+ TorgoSingleDockable ret = null ;
257
+ if ("Display" .equals (id )) {
258
+ ret = new TorgoSingleDockable (id , torgoCanvas .getComponent ());
259
+ } else {
260
+ for (ImmutablePair <String , Component > pair : torgoPanel .getTorgoComponents ()) {
261
+ if (pair .left .equals (id )) {
262
+ ret = new TorgoSingleDockable (pair .left , pair .right );
263
+ }
264
+ }
265
+ }
266
+ if (ret != null ) {
267
+ ImageIcon icon = Main .getIcon ("layouts/" + ret .getTitleText ().toLowerCase () + "-24x24.png" );
268
+ ret .setTitleIcon (icon );
186
269
}
187
- });
270
+ return ret ;
271
+ }
272
+ });
188
273
189
- contentPane .add (splitPane );
190
- } else {
191
- contentPane .add (torgoPanel .getComponent ());
274
+ // Try to load a saved layout.
275
+ // If no layout exists or it fails, load from CLASSPATH/resources.
276
+ // If that fails, dynamically generate something.
277
+ String layoutFileName = PathUtils .getApplicationConfigDirectory (TorgoInfo .INSTANCE ) + java .io .File .separatorChar + getLang () + "-layout.xml" ;
278
+ File layoutFile = new File (layoutFileName );
279
+ boolean loaded = false ;
280
+ if (layoutFile .exists ()) {
281
+ try {
282
+ XElement elem = XIO .readUTF (new FileInputStream (layoutFile ));
283
+ dockControl .readXML (elem );
284
+ loaded = true ;
285
+ } catch (FileNotFoundException ex ) {
286
+ Logger .getLogger (ControllerBase .class .getName ()).log (Level .SEVERE , null , ex );
287
+ } catch (IOException ex ) {
288
+ Logger .getLogger (ControllerBase .class .getName ()).log (Level .SEVERE , null , ex );
289
+ }
290
+ }
291
+ if (!loaded ) {
292
+ try {
293
+ java .util .Enumeration <URL > resources = ClassLoader .getSystemClassLoader ().getResources ("layouts/" + this .getLang () + "-layout.xml" );
294
+ XElement elem = XIO .readUTF (resources .nextElement ().openStream ());
295
+ dockControl .readXML (elem );
296
+ loaded = true ;
297
+ } catch (IOException | java .util .NoSuchElementException ex ) {
298
+ Logger .getLogger (ControllerBase .class .getName ()).log (Level .WARNING , "Layout Error: Auto-generating: {0}" , ex .getMessage ());
299
+ }
300
+ }
301
+ if (!loaded ) {
302
+ XElement elem = createLayout (torgoCanvas != null ? torgoCanvas .getComponent () : null , torgoPanel .getTorgoComponents ());
303
+ dockControl .readXML (elem );
192
304
}
193
305
194
306
JMenuBar mb = createMenuBar ();
@@ -291,13 +403,19 @@ public void windowOpened(WindowEvent e) {
291
403
292
404
/**
293
405
* We only care if the window is closing so we can kill the
294
- * interpreter thread.
406
+ * interpreter thread and save the layout .
295
407
*
296
408
* @param e
297
409
*/
298
410
@ Override
299
411
public void windowClosing (WindowEvent e ) {
300
412
stopInterpreter ();
413
+ try {
414
+ String layoutFile = PathUtils .getApplicationConfigDirectory (TorgoInfo .INSTANCE ) + java .io .File .separatorChar + getLang () + "-layout.xml" ;
415
+ dockControl .writeXML (new java .io .File (layoutFile ));
416
+ } catch (IOException ex ) {
417
+ Logger .getLogger (ControllerBase .class .getName ()).log (Level .SEVERE , null , ex );
418
+ }
301
419
}
302
420
303
421
@ Override
@@ -517,9 +635,6 @@ public void startInterpreter() {
517
635
TorgoToolkit .getVisualization (item .getText ()).create ().watch (this .getLang (), this , interp );
518
636
}
519
637
}
520
- // viz.stream().filter((item) -> (item.getState())).map((item) -> TorgoToolkit.getVisualization(item.getText()).create()).forEach((visualization) -> {
521
- // visualization.watch(this.getLang(), this, interp);
522
- // });
523
638
524
639
for (InterpreterListener l : listeners .getListeners ()) {
525
640
interp .addInterpreterListener (l );
@@ -568,9 +683,6 @@ public void debugInterpreter() {
568
683
TorgoToolkit .getVisualization (item .getText ()).create ().watch (this .getLang (), this , interp );
569
684
}
570
685
}
571
- // viz.stream().filter((item) -> (item.getState())).map((item) -> TorgoToolkit.getVisualization(item.getText()).create()).forEach((visualization) -> {
572
- // visualization.watch(this.getLang(), this, interp);
573
- // });
574
686
575
687
for (InterpreterListener l : listeners .getListeners ()) {
576
688
interp .addInterpreterListener (l );
0 commit comments