~seh999/jcog/proto3

« back to all changes in this revision

Viewing changes to spacetime/src.ui/opencog/spacetime/ui/viewerapp/Navigator.java

  • Committer: SeH
  • Date: 2009-09-19 22:59:48 UTC
  • Revision ID: seh999@gmail.com-20090919225948-q3ab80xa57i74mm6
start of major jReality refactoring

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/**
2
 
 *
3
 
 * This file is part of jReality. jReality is open source software, made
4
 
 * available under a BSD license:
5
 
 *
6
 
 * Copyright (c) 2003-2006, jReality Group: Charles Gunn, Tim Hoffmann, Markus
7
 
 * Schmies, Steffen Weissmann.
8
 
 *
9
 
 * All rights reserved.
10
 
 *
11
 
 * Redistribution and use in source and binary forms, with or without
12
 
 * modification, are permitted provided that the following conditions are met:
13
 
 *
14
 
 * - Redistributions of source code must retain the above copyright notice, this
15
 
 *   list of conditions and the following disclaimer.
16
 
 *
17
 
 * - Redistributions in binary form must reproduce the above copyright notice,
18
 
 *   this list of conditions and the following disclaimer in the documentation
19
 
 *   and/or other materials provided with the distribution.
20
 
 *
21
 
 * - Neither the name of jReality nor the names of its contributors nor the
22
 
 *   names of their associated organizations may be used to endorse or promote
23
 
 *   products derived from this software without specific prior written
24
 
 *   permission.
25
 
 *
26
 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
27
 
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28
 
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29
 
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
30
 
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31
 
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32
 
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33
 
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34
 
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35
 
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36
 
 * POSSIBILITY OF SUCH DAMAGE.
37
 
 *
38
 
 */
39
 
 
40
 
 
41
 
package opencog.spacetime.ui.viewerapp;
42
 
 
43
 
import java.awt.Component;
44
 
import java.awt.Container;
45
 
import java.awt.Dimension;
46
 
import java.awt.GridBagConstraints;
47
 
import java.awt.GridBagLayout;
48
 
import java.awt.GridLayout;
49
 
import java.awt.event.ActionEvent;
50
 
import java.awt.event.MouseAdapter;
51
 
import java.awt.event.MouseEvent;
52
 
 
53
 
import javax.swing.AbstractAction;
54
 
import javax.swing.Action;
55
 
import javax.swing.ActionMap;
56
 
import javax.swing.BorderFactory;
57
 
import javax.swing.JCheckBox;
58
 
import javax.swing.JMenu;
59
 
import javax.swing.JPanel;
60
 
import javax.swing.JPopupMenu;
61
 
import javax.swing.JScrollPane;
62
 
import javax.swing.JSeparator;
63
 
import javax.swing.JSplitPane;
64
 
import javax.swing.JTree;
65
 
import javax.swing.KeyStroke;
66
 
import javax.swing.event.TreeSelectionEvent;
67
 
import javax.swing.event.TreeSelectionListener;
68
 
import javax.swing.tree.TreePath;
69
 
import javax.swing.tree.TreeSelectionModel;
70
 
 
71
 
import opencog.spacetime.scene.SceneGraphComponent;
72
 
import opencog.spacetime.scene.Viewer;
73
 
import opencog.spacetime.scene.proxy.tree.SceneTreeNode;
74
 
import opencog.spacetime.ui.treeview.JTreeRenderer;
75
 
import opencog.spacetime.ui.treeview.SceneTreeModel;
76
 
import opencog.spacetime.ui.treeview.SceneTreeModel.TreeTool;
77
 
 
78
 
import de.jtem.beans.BooleanEditor;
79
 
import de.jtem.beans.EditorSpawner;
80
 
import de.jtem.beans.InspectorPanel;
81
 
import de.jtem.beans.NumberSpinnerEditor;
82
 
 
83
 
 
84
 
/**
85
 
 * Scene tree and inspector panel for a given scene graph.
86
 
 * 
87
 
 * @author msommer
88
 
 */
89
 
public class Navigator implements SelectionListener {
90
 
 
91
 
        private InspectorPanel inspector;
92
 
        private JTree sceneTree;
93
 
        private SceneTreeModel treeModel;
94
 
        private TreeSelectionModel tsm;
95
 
 
96
 
        private SelectionManager selectionManager;
97
 
        private SelectionManager externalSelectionManager;
98
 
        private Viewer viewer;  //the underlying viewer
99
 
 
100
 
        private Container navigator;
101
 
        private Component parentComp;
102
 
        
103
 
        private Component toolBar;
104
 
        private JCheckBox receiveCheckBox;
105
 
        private JCheckBox propagateCheckBox;
106
 
 
107
 
 
108
 
        /**
109
 
         * @param sceneRoot the scene root
110
 
         * @param selectionManager the underlying selection manager
111
 
         */
112
 
        public Navigator(Viewer viewer) {
113
 
                this(viewer, null);
114
 
        }
115
 
 
116
 
 
117
 
        /**
118
 
         * @param sceneRoot the scene root
119
 
         * @param selectionManager the underlying selection manager
120
 
         * @param parentComp used by dialogs from the context menu (<code>null</code> allowed)
121
 
         */
122
 
        public Navigator(Viewer viewer, Component parentComp) {
123
 
 
124
 
                externalSelectionManager = SelectionManagerImpl.selectionManagerForViewer(viewer);
125
 
                selectionManager = new SelectionManagerImpl(externalSelectionManager.getDefaultSelection());
126
 
                //selectionManager.addSelectionListener(this);
127
 
                toolBar = createToolBar();
128
 
//              setPropagateSelections(true);
129
 
                setReceiveSelections(true);
130
 
 
131
 
                this.parentComp = parentComp;
132
 
 
133
 
                inspector = new InspectorPanel(false);
134
 
                BooleanEditor.setNameOfNull("inherit");
135
 
                EditorSpawner.setNameOfNull("inherit");
136
 
                EditorSpawner.setNameOfCreation("inherited");
137
 
                NumberSpinnerEditor.setNameOfNull("inherit");
138
 
                NumberSpinnerEditor.setNameOfCreation("inherited");
139
 
                //EditorManager.registerEditor(Texture2D.class, ObjectEditor.class);
140
 
 
141
 
                sceneTree = new JTree();
142
 
                treeModel = new SceneTreeModel(viewer.getSceneRoot());
143
 
 
144
 
                sceneTree.setModel(treeModel);
145
 
                //set default (anchor) selection (use the selection manager's default)
146
 
                sceneTree.setAnchorSelectionPath(new TreePath(treeModel.convertSelection(selectionManager.getDefaultSelection())));
147
 
                sceneTree.setCellRenderer(new JTreeRenderer());
148
 
                sceneTree.getInputMap().put(KeyStroke.getKeyStroke("ENTER"), "toggle");  //collaps/expand nodes with ENTER
149
 
 
150
 
                tsm = sceneTree.getSelectionModel();
151
 
                tsm.setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
152
 
 
153
 
                tsm.addTreeSelectionListener(new SelectionListener(){
154
 
 
155
 
                        public void selectionChanged(SelectionEvent e) {
156
 
 
157
 
                                Selection currentSelection = e.getSelection();
158
 
                                //update inspector
159
 
                                inspector.setObject(currentSelection.getLastElement());
160
 
                                inspector.refresh();
161
 
                                
162
 
                                //update selection managers
163
 
                                selectionManager.setSelection(currentSelection);
164
 
                                if (isPropagateSelections()) externalSelectionManager.setSelection(currentSelection);  //does nothing if already selected
165
 
                        }
166
 
                });
167
 
 
168
 
                try {  //set default selection
169
 
                        tsm.setSelectionPath(new TreePath(treeModel.convertSelection(selectionManager.getDefaultSelection())));  //select current selection
170
 
                } catch (Exception e) {
171
 
                        //no valid default selection
172
 
                }
173
 
                
174
 
//              SceneGraphPath sgp = sm.getSelectionPath();
175
 
//              if (sgp != null && sgp.isValid()) 
176
 
//                  tsm.setSelectionPath(new TreePath(treeModel.convertSelection(sm.getSelection())));  //select current selection
177
 
                
178
 
                setupContextMenu();
179
 
        }
180
 
 
181
 
        
182
 
        public void selectionChanged(opencog.spacetime.ui.viewerapp.SelectionEvent e) {
183
 
                //convert selection of manager into TreePath
184
 
                Object[] selection = null;
185
 
                try {
186
 
                        selection = treeModel.convertSelection(e.getSelection());                       
187
 
                        TreePath path = new TreePath(selection);
188
 
 
189
 
                        if (e.nodeSelected() && !path.equals(tsm.getSelectionPath()))  //compare paths only if a node is selected  
190
 
                                tsm.setSelectionPath(path);
191
 
 
192
 
                } catch (NullPointerException npe) {
193
 
                        //SelectionManager's selection is not valid, 
194
 
                        //i.e. has no representation in tree view (scene graph)
195
 
                }
196
 
        }
197
 
 
198
 
 
199
 
        public InspectorPanel getInspector() {
200
 
                return inspector;
201
 
        }
202
 
 
203
 
 
204
 
        public JTree getSceneTree() {
205
 
                return sceneTree;
206
 
        }
207
 
 
208
 
 
209
 
        public TreeSelectionModel getTreeSelectionModel() {
210
 
                return tsm;
211
 
        }
212
 
 
213
 
 
214
 
        public SceneGraphComponent getSceneRoot() {
215
 
                return viewer.getSceneRoot();
216
 
        }
217
 
 
218
 
 
219
 
        public Selection getSelection() {
220
 
                return selectionManager.getSelection();
221
 
        }
222
 
 
223
 
 
224
 
        private void setupContextMenu() {
225
 
 
226
 
                final JPopupMenu cm = new JPopupMenu();
227
 
                cm.setLightWeightPopupEnabled(false);
228
 
 
229
 
                //create content of context menu
230
 
                JMenu editMenu = null;
231
 
                ActionMap editActions = null;
232
 
                try {
233
 
                        editMenu = ViewerAppMenu.createEditMenu(parentComp, selectionManager);
234
 
                        editActions = ViewerAppMenu.updateActionMap(editMenu.getActionMap(), editMenu);
235
 
                } catch (Exception e) {
236
 
                        return;  //menu or actions not in classpath
237
 
                }
238
 
                for (Component c : editMenu.getMenuComponents()) cm.add(c);
239
 
 
240
 
                //add listener to the navigator's tree
241
 
                sceneTree.addMouseListener(new MouseAdapter() {
242
 
 
243
 
                        public void mousePressed( MouseEvent e ) {
244
 
                                handlePopup( e );
245
 
                        }
246
 
 
247
 
                        public void mouseReleased( MouseEvent e ) {
248
 
                                handlePopup( e );
249
 
                        }
250
 
 
251
 
                        private void handlePopup( MouseEvent e ) {
252
 
                                if ( e.isPopupTrigger() ) {
253
 
                                        TreePath path = sceneTree.getPathForLocation( e.getX(), e.getY() );
254
 
                                        if ( path != null ) {
255
 
                                                tsm.clearSelection();  //ensures that SelectionListeners are notified even if path did not change
256
 
                                                tsm.setSelectionPath( path );
257
 
                                                cm.show( e.getComponent(), e.getX(), e.getY()+10 );
258
 
                                        }
259
 
                                }
260
 
                        }
261
 
                });
262
 
                
263
 
                //set up input and action map to match actions of context menu instead of viewers menu bar
264
 
                try {
265
 
                        Object[] keys = editActions.keys();
266
 
                        for (int i = 0; i < keys.length; i++) {
267
 
                                KeyStroke key = (KeyStroke) keys[i];
268
 
                                sceneTree.getInputMap().put(key, key);
269
 
                                sceneTree.getActionMap().put(key, editActions.get(key));
270
 
                        }
271
 
                } catch (Exception e) {
272
 
                        //e.printStackTrace();
273
 
                }
274
 
        }
275
 
 
276
 
 
277
 
        /**
278
 
         * Get the navigator as a Component.
279
 
         * @return the navigator
280
 
         */
281
 
        public Component getComponent() {
282
 
 
283
 
                if (navigator == null) {
284
 
                        sceneTree.setBorder(BorderFactory.createEmptyBorder(4,4,4,4));
285
 
                        JScrollPane top = new JScrollPane(sceneTree);
286
 
                        top.setPreferredSize(new Dimension(1, 1));
287
 
                        top.setBorder(BorderFactory.createEmptyBorder());
288
 
 
289
 
                        inspector.setBorder(BorderFactory.createEmptyBorder(4,4,4,4));
290
 
                        JScrollPane bottom = new JScrollPane(inspector);
291
 
                        bottom.setPreferredSize(new Dimension(1, 1));
292
 
                        bottom.setBorder(BorderFactory.createEmptyBorder());
293
 
 
294
 
                        JSplitPane navigator = new JSplitPane(JSplitPane.VERTICAL_SPLIT, top, bottom);
295
 
                        navigator.setResizeWeight(0.6);
296
 
                        navigator.setContinuousLayout(true);
297
 
                        navigator.setOneTouchExpandable(true);
298
 
 
299
 
                        this.navigator = new JPanel();
300
 
                        this.navigator.setLayout(new GridBagLayout());
301
 
                        GridBagConstraints c = new GridBagConstraints();
302
 
                        c.fill = GridBagConstraints.BOTH;
303
 
                        c.gridwidth = GridBagConstraints.REMAINDER;
304
 
                        c.weightx = 1.0;
305
 
                        c.weighty = 0.0;
306
 
                        this.navigator.add(toolBar, c);
307
 
                        this.navigator.add(new JSeparator(), c);
308
 
                        c.weighty = 1.0;
309
 
                        this.navigator.add(navigator, c);
310
 
                }
311
 
 
312
 
                return navigator;
313
 
        }
314
 
 
315
 
        
316
 
        private Component createToolBar() {
317
 
                
318
 
                JPanel checkerPanel = new JPanel();
319
 
                checkerPanel.setLayout(new GridLayout(1, 2));
320
 
//              JToolBar jtb = new JToolBar(SwingConstants.HORIZONTAL);
321
 
//              jtb.setFloatable(false);
322
 
                
323
 
                Action a;
324
 
                propagateCheckBox = new JCheckBox();
325
 
//              final URL propagateImg = Navigator.class.getResource("propagate.png");
326
 
                a = new AbstractAction("Propagate"){
327
 
                        
328
 
                        private static final long serialVersionUID = 1L;
329
 
                        {       
330
 
                                putValue(Action.SHORT_DESCRIPTION, "Propagate selections to the SelectionManager");
331
 
                        }
332
 
                        public void actionPerformed(ActionEvent e) {
333
 
                                // nothing to do
334
 
                        }
335
 
                };
336
 
                propagateCheckBox.setAction(a);
337
 
                checkerPanel.add(propagateCheckBox);
338
 
                receiveCheckBox = new JCheckBox();
339
 
                a = new AbstractAction("Receive"){
340
 
                        private static final long serialVersionUID = 1L;
341
 
                        {
342
 
                                putValue(Action.SHORT_DESCRIPTION, "Receive selections from the SelectionManager");
343
 
                        }
344
 
                        public void actionPerformed(ActionEvent e) {
345
 
                                updateReceiveSelections();
346
 
                        }
347
 
                };
348
 
                receiveCheckBox.setAction(a);
349
 
                checkerPanel.add(receiveCheckBox);
350
 
 
351
 
                return checkerPanel;
352
 
        }
353
 
 
354
 
        /**
355
 
         * Receive selections from the underlying viewer's selection manager.
356
 
         */
357
 
        public void setReceiveSelections(boolean receive) {
358
 
                receiveCheckBox.setSelected(receive);
359
 
        }
360
 
        
361
 
        public boolean isReceiveSelections() {
362
 
                return receiveCheckBox.isSelected();
363
 
        }
364
 
        
365
 
        private void updateReceiveSelections() {
366
 
                if (receiveCheckBox.isSelected()) {
367
 
                        externalSelectionManager.addSelectionListener(Navigator.this);
368
 
                } else {
369
 
                        externalSelectionManager.removeSelectionListener(Navigator.this);
370
 
                }
371
 
        }
372
 
 
373
 
        public boolean isPropagateSelections() {
374
 
                return propagateCheckBox.isSelected();
375
 
        }
376
 
        
377
 
        /**
378
 
         * Propagate selections to the underlying viewer's selection manager.
379
 
         */
380
 
        public void setPropagateSelections(boolean propagate) {
381
 
                propagateCheckBox.setSelected(propagate);
382
 
        }
383
 
 
384
 
//      -- INNER CLASSES -----------------------------------
385
 
 
386
 
 
387
 
 
388
 
        public static abstract class SelectionListener implements TreeSelectionListener {
389
 
 
390
 
                public abstract void selectionChanged(SelectionEvent e);
391
 
 
392
 
                public void valueChanged(TreeSelectionEvent e) {
393
 
 
394
 
                        boolean[] areNew = new boolean[e.getPaths().length];
395
 
                        for (int i = 0; i < areNew.length; i++)
396
 
                                areNew[i] = e.isAddedPath(i);
397
 
 
398
 
                        SelectionEvent se = new SelectionEvent(e.getSource(), e.getPaths(), 
399
 
                                        areNew, e.getOldLeadSelectionPath(), e.getNewLeadSelectionPath()); 
400
 
 
401
 
                        selectionChanged(se);
402
 
                }
403
 
 
404
 
        }  //end of class SelectionListener
405
 
 
406
 
 
407
 
        public static class SelectionEvent extends TreeSelectionEvent {
408
 
                
409
 
                private static final long serialVersionUID = 1L;
410
 
 
411
 
                /** calls TreeSelectionEvent(...) */
412
 
                public SelectionEvent(Object source, TreePath[] paths, boolean[] areNew, TreePath oldLeadSelectionPath, TreePath newLeadSelectionPath) {
413
 
                        super(source, paths, areNew, oldLeadSelectionPath, newLeadSelectionPath);
414
 
                }
415
 
 
416
 
                private Object convert(Object o) {
417
 
                        if (o instanceof SceneTreeNode)
418
 
                                return ((SceneTreeNode) o).getNode();
419
 
                        else if (o instanceof TreeTool)
420
 
                                return ((TreeTool) o).getTool();
421
 
 
422
 
                        return o;
423
 
                }
424
 
 
425
 
                /**
426
 
                 * Converts the TreePath of the current selection into a Selection object.  
427
 
                 * @return the current selection
428
 
                 */
429
 
                public Selection getSelection() {
430
 
                        Selection selection = new Selection();
431
 
                        Object[] treePath = getPath().getPath();
432
 
                        for (int i = 0; i < treePath.length; i++)
433
 
                                selection.push( convert(treePath[i]) );
434
 
                        return selection;
435
 
                }
436
 
 
437
 
        }  //end of class SelectionEvent
438
 
 
439
 
}
 
 
b'\\ No newline at end of file'