Warning: Can't use blame annotator:
svn blame failed on trunk/src/scriptbuilder/gui/panels/ScriptBuilderTimelinePanel.java: ("Can't find a temporary directory: Internal error", 20014)

source: tmcsimulator-scriptbuilder/trunk/src/scriptbuilder/gui/panels/ScriptBuilderTimelinePanel.java @ 75

Revision 75, 13.7 KB checked in by jdalbey, 9 years ago (diff)

ScriptBuilderTimelinePanel?.java: Add local main to display this panel only.

RevLine 
1package scriptbuilder.gui.panels;
2
3import event.editor.Editor;
4import event.editor.Properties;
5import java.awt.BorderLayout;
6import java.awt.Dimension;
7import java.awt.Graphics;
8import java.awt.Graphics2D;
9import java.awt.event.MouseEvent;
10import java.io.File;
11import java.util.HashMap;
12import java.util.Map;
13import javax.swing.JFrame;
14import javax.swing.JPanel;
15import javax.swing.event.MouseInputAdapter;
16import scriptbuilder.gui.IncidentEditorFrame;
17import scriptbuilder.gui.ScriptBuilderFrame;
18import scriptbuilder.gui.ScriptBuilderGuiConstants;
19import scriptbuilder.gui.drawers.CursorDrawer;
20import scriptbuilder.gui.drawers.EventIconDrawer;
21import scriptbuilder.gui.drawers.IncidentTimelineDrawer;
22import scriptbuilder.structures.ScriptEvent;
23import scriptbuilder.structures.ScriptEvent.ScriptEventType;
24import scriptbuilder.structures.ScriptIncident;
25import scriptbuilder.structures.SimulationScript;
26import scriptbuilder.structures.TimeSlice;
27import scriptbuilder.structures.events.I_ScriptEvent;
28
29/**
30 * Represents a single incident timeline in the GUI. Listens for mouse actions.
31 *
32 * @author Greg Eddington <geddingt@calpoly.edu>
33 * @author Bryan McGuffin
34 * @version 2017/06/30
35 */
36public class ScriptBuilderTimelinePanel extends JPanel
37{
38
39    /**
40     * The incident this panel represents.
41     */
42    ScriptIncident incident;
43    /**
44     * If true, this panel is in its minimized state.
45     */
46    //boolean collapsed;
47    /**
48     * If false, this panel won't be drawn.
49     */
50    boolean visible;
51    /**
52     * If true, this panel has focus.
53     */
54    boolean focused;
55
56    int cursorTime, lastSlice, x, y;
57
58    /**
59     * The map representing the properties of this incident's events. Keys:
60     * event types. Values: Properties objects for those events.
61     */
62    Map<ScriptEventType, Properties> eventTypeToPropertyMap;
63
64    /**
65     * Listener for the mouse. Receives notifications when the mouse enters,
66     * exits, moves through, or clicks inside the panel.
67     */
68    public class IncidentTimelineMouseListener extends MouseInputAdapter
69    {
70
71        /**
72         * Action to take when the mouse enters the panel. Here, the incident
73         * corresponding to this panel gains focus.
74         *
75         * @param e the mouse event
76         */
77        @Override
78        public void mouseEntered(MouseEvent e)
79        {
80            incident.setIncidentActive();
81            focused = true;
82        }
83
84        /**
85         * Action to take when the mouse leaves the panel. Here, the incident
86         * loses focus and the panel gets repainted.
87         *
88         * @param e the mouse event
89         */
90        @Override
91        public void mouseExited(MouseEvent e)
92        {
93            focused = false;
94            repaint();
95        }
96
97        /**
98         * Determine if the mouse click happened within a valid timeSlice on
99         * this incident; if so, activate the Editor window for that timeSlice.
100         *
101         * @param e the mouse event
102         */
103        @Override
104        public void mouseClicked(MouseEvent e)
105        {
106            Editor ed = new Editor();
107            ScriptBuilderFrame f = null;
108            IncidentEditorFrame g = null;
109            if (getTopLevelAncestor() instanceof ScriptBuilderFrame)
110            {
111                f = (ScriptBuilderFrame) getTopLevelAncestor();
112            }
113            else if (getTopLevelAncestor() instanceof IncidentEditorFrame)
114            {
115                g = (IncidentEditorFrame) getTopLevelAncestor();
116            }
117
118            x = cursorTime = e.getX();
119            y = e.getY();
120
121            if (e.getX() % ScriptBuilderGuiConstants.PIXEL_WIDTH_PER_HORIZONTAL_TICK
122                    > ScriptBuilderGuiConstants.PIXEL_WIDTH_PER_HORIZONTAL_TICK / 2)
123            {
124                cursorTime += ScriptBuilderGuiConstants.PIXEL_WIDTH_PER_HORIZONTAL_TICK
125                        - e.getX()
126                        % ScriptBuilderGuiConstants.PIXEL_WIDTH_PER_HORIZONTAL_TICK;
127            }
128            else
129            {
130                cursorTime -= e.getX()
131                        % ScriptBuilderGuiConstants.PIXEL_WIDTH_PER_HORIZONTAL_TICK;
132            }
133
134            int newSlice = (cursorTime / ScriptBuilderGuiConstants.PIXEL_WIDTH_PER_HORIZONTAL_TICK);
135            newSlice *= ScriptBuilderGuiConstants.HORIZONTAL_TICK_RESOLUTION;
136            /**
137             * Check if click is out of bounds *
138             */
139            if (newSlice < 0 || incident == null)
140            {
141                return;
142            }
143
144            if (incident.slices.get(newSlice) != null)
145
146            {
147                for (I_ScriptEvent se : incident.slices.get(newSlice).events)
148                {
149                    ed.addProperty(eventTypeToPropertyMap.get(se.getScriptEventType()), se);
150                }
151            }
152
153            /**
154             * Add a new icon if left mouse button was clicked *
155             */
156            if (e.getButton() == MouseEvent.BUTTON1)
157            {
158                if (getTopLevelAncestor() instanceof ScriptBuilderFrame)
159                {
160                    if (f.currentEventType != null)
161                    {
162                        I_ScriptEvent s = ScriptEvent.factoryByType(f.currentEventType);
163                        ed.addProperty(eventTypeToPropertyMap.get(f.currentEventType), s);
164                        if (incident.slices.get(newSlice) == null)
165                        {
166                            incident.addNewEvent(s, newSlice);
167                        }
168                        else
169                        {
170                            incident.slices.get(newSlice).addEvent(s);
171                        }
172                        f.update(f.getScript(), f.getScript());
173                    }
174                }
175                if (getTopLevelAncestor() instanceof IncidentEditorFrame)
176                {
177                    if (g.currentEventType != null)
178                    {
179                        I_ScriptEvent s = ScriptEvent.factoryByType(g.currentEventType);
180                        ed.addProperty(eventTypeToPropertyMap.get(g.currentEventType), s);
181                        if (incident.slices.get(newSlice) == null)
182                        {
183                            incident.addNewEvent(s, newSlice);
184                        }
185                        else
186                        {
187                            incident.slices.get(newSlice).addEvent(s);
188                        }
189                        g.update(null, g.getIncident());
190                    }
191                }
192            }
193
194            if (incident.slices.get(newSlice) != null
195                    && getTopLevelAncestor() instanceof IncidentEditorFrame)
196            {
197                ed.setVisible(true);
198            }
199        }
200
201        /**
202         * Determine if the mouse is now hovering over a valid timeslice; if so,
203         * alter tooltip text and info window text to reflect the new timeslice.
204         *
205         * @param e the mouse event
206         */
207        @Override
208        public void mouseMoved(MouseEvent e)
209        {
210            x = cursorTime = e.getX();
211            y = e.getY();
212
213            if (e.getX() % ScriptBuilderGuiConstants.PIXEL_WIDTH_PER_HORIZONTAL_TICK
214                    > ScriptBuilderGuiConstants.PIXEL_WIDTH_PER_HORIZONTAL_TICK / 2)
215            {
216                cursorTime += ScriptBuilderGuiConstants.PIXEL_WIDTH_PER_HORIZONTAL_TICK
217                        - e.getX()
218                        % ScriptBuilderGuiConstants.PIXEL_WIDTH_PER_HORIZONTAL_TICK;
219            }
220            else
221            {
222                cursorTime -= e.getX()
223                        % ScriptBuilderGuiConstants.PIXEL_WIDTH_PER_HORIZONTAL_TICK;
224            }
225
226            if (incident != null)
227            {
228                int newSlice = (cursorTime / ScriptBuilderGuiConstants.PIXEL_WIDTH_PER_HORIZONTAL_TICK);
229                newSlice *= ScriptBuilderGuiConstants.HORIZONTAL_TICK_RESOLUTION;
230                if (newSlice >= 0 && incident.slices.get(newSlice) != null)
231                {
232                    incident.setSliceActive(newSlice);
233                    lastSlice = newSlice;
234                    String newToolTip;
235
236                    newToolTip = incident.slices.get(newSlice).getToolTipText(y);
237
238                    setToolTipText((newToolTip == null || newToolTip.equals(""))
239                            ? null : newToolTip);
240                }
241            }
242
243            repaint();
244        }
245    }
246
247    /**
248     * Constructor. Generates a HashMap of all possible event types.
249     */
250    public ScriptBuilderTimelinePanel()
251    {
252        super();
253
254//        FACILITATOR_EVAL_EVENT, RADIO_EVAL_EVENT
255        eventTypeToPropertyMap = new HashMap();
256        eventTypeToPropertyMap.put(ScriptEventType.AUDIO_EVENT, Properties.Audio);
257        eventTypeToPropertyMap.put(ScriptEventType.CAD_EVENT, Properties.CADLog);
258        eventTypeToPropertyMap.put(ScriptEventType.CCTV_EVENT, Properties.CCTV);
259        eventTypeToPropertyMap.put(ScriptEventType.CHP_RADIO_EVENT, Properties.CHPRadio);
260        eventTypeToPropertyMap.put(ScriptEventType.PARAMICS_EVENT, Properties.Paramics);
261        eventTypeToPropertyMap.put(ScriptEventType.TOW_EVENT, Properties.Tow);
262        eventTypeToPropertyMap.put(ScriptEventType.UNIT_EVENT, Properties.Unit);
263        eventTypeToPropertyMap.put(ScriptEventType.WITNESS_EVENT, Properties.Witness);
264        eventTypeToPropertyMap.put(ScriptEventType.MAINTENANCE_RADIO_EVENT, Properties.MaintenanceRadio);
265        eventTypeToPropertyMap.put(ScriptEventType.TMT_RADIO_EVENT, Properties.TMTRadio);
266        eventTypeToPropertyMap.put(ScriptEventType.TELEPHONE_EVENT, Properties.Telephone);
267        eventTypeToPropertyMap.put(ScriptEventType.ATMS_EVAL_EVENT, Properties.ATMS);
268        eventTypeToPropertyMap.put(ScriptEventType.ACTIVITY_LOG_EVAL_EVENT, Properties.ActivityLog);
269        eventTypeToPropertyMap.put(ScriptEventType.CAD_EVAL_EVENT, Properties.CAD);
270        eventTypeToPropertyMap.put(ScriptEventType.CMS_EVAL_EVENT, Properties.CMS);
271        eventTypeToPropertyMap.put(ScriptEventType.FACILITATOR_EVAL_EVENT, Properties.Facilitator);
272        eventTypeToPropertyMap.put(ScriptEventType.RADIO_EVAL_EVENT, Properties.Radio);
273
274        // Add the mouse listener
275        IncidentTimelineMouseListener mouseListener
276                = new IncidentTimelineMouseListener();
277        addMouseMotionListener(mouseListener);
278        addMouseListener(mouseListener);
279    }
280
281    /**
282     * Update the panel if it's changed collapsed status. Redraw it with the
283     * correct dimensions for its status.
284     *
285     * @param incident the incident this panel represents
286     */
287    public void timelinePanelUpdate(ScriptIncident incident)
288    {
289        this.incident = incident;
290        this.visible = incident != null;
291
292        Dimension newSize;
293        if (visible)
294        {
295
296            newSize = new Dimension(((incident.length + incident.offset)
297                    / ScriptBuilderGuiConstants.HORIZONTAL_TICK_RESOLUTION
298                    * ScriptBuilderGuiConstants.PIXEL_WIDTH_PER_HORIZONTAL_TICK)
299                    + ScriptBuilderGuiConstants.EVENT_ICON_WIDTH,
300                    ScriptBuilderGuiConstants.TIMELINE_COLLAPSED_HEIGHT
301                    + ScriptBuilderGuiConstants.SCRIPT_EVENT_ICON_STEP * 2);
302
303        }
304        else
305        {
306            newSize = new Dimension(0, 0);
307        }
308        this.setSize(newSize);
309        this.setPreferredSize(newSize);
310
311        invalidate();
312    }
313
314    /**
315     * Redraw this panel and all the icons inside it. If user is holding an
316     * event, draw that icon under the mouse.
317     *
318     * @param g the graphics component
319     */
320    @Override
321    public void paint(Graphics g)
322    {
323        super.paint(g);
324
325        if (!visible)
326        {
327            return;
328        }
329
330        Graphics2D g2d = (Graphics2D) g;
331        if (getTopLevelAncestor() instanceof ScriptBuilderFrame)
332        {
333            IncidentTimelineDrawer.DrawScriptBuilderTimeline(g2d, incident);
334        }
335        if (getTopLevelAncestor() instanceof IncidentEditorFrame)
336        {
337            IncidentTimelineDrawer.DrawIncidentTimeline(g2d, incident, false);
338        }
339
340        if (focused)
341        {
342            CursorDrawer.DrawCursor(g2d, cursorTime, false);
343            if (this.getTopLevelAncestor() instanceof ScriptBuilderFrame)
344            {
345                if (((ScriptBuilderFrame) this.getTopLevelAncestor()).currentEventType != null)
346                {
347                    EventIconDrawer.DrawEventIcon(g2d,
348                            ((ScriptBuilderFrame) this.getTopLevelAncestor()).currentEventType,
349                            x + 5, y + 10);
350                }
351            }
352            if (this.getTopLevelAncestor() instanceof IncidentEditorFrame)
353            {
354                if (((IncidentEditorFrame) this.getTopLevelAncestor()).currentEventType != null)
355                {
356                    EventIconDrawer.DrawEventIcon(g2d,
357                            ((IncidentEditorFrame) this.getTopLevelAncestor()).currentEventType,
358                            x + 5, y + 10);
359                }
360            }
361        }
362    }
363
364    /**
365     * Local main for viewing this panel only.
366     *
367     * @author jdalbey
368     * @param args not used
369     */
370    public static void main(String[] args)
371    {
372        JFrame frame = new JFrame("FrameDemo");
373        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
374
375        ScriptBuilderTimelinePanel pnl = new ScriptBuilderTimelinePanel();
376
377        // Create a script
378        File inFile = new File("test/scriptbuilder/structures/test_input_file.xml");
379        SimulationScript script = new SimulationScript();
380        script.loadScriptFromFile(inFile);
381        // retrieve a single incident from the script
382        ScriptIncident inci = script.incidents.get(1);
383        // update this panel with an incident
384        pnl.timelinePanelUpdate(inci);
385
386        frame.getContentPane().add(pnl, BorderLayout.CENTER);
387        frame.pack();
388
389        frame.setVisible(true);
390
391    }
392}
Note: See TracBrowser for help on using the repository browser.