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

source: tmcsimulator-scriptbuilder/trunk/src/scriptbuilder/gui/panels/IncidentTimelinePanel.java @ 79

Revision 79, 14.0 KB checked in by bmcguffin, 9 years ago (diff)

Renamed ScriptBuilderTimelinePanel? to IncidentTimelinePanel?. Renamed ScriptBuilderNumberPanel? to IncidentNumberPanel?.

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 IncidentTimelinePanel 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 IncidentTimelinePanel()
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//        jdalbey removed this decision and replaced it with ELSE clause
332//                so it will work with any alternate ancestor.
333//        if (getTopLevelAncestor() instanceof ScriptBuilderFrame)
334//        {
335//            IncidentTimelineDrawer.DrawScriptBuilderTimeline(g2d, incident);
336//        }
337        if (getTopLevelAncestor() instanceof IncidentEditorFrame)
338        {
339            IncidentTimelineDrawer.DrawIncidentTimeline(g2d, incident, false);
340        }
341        else
342        {
343            IncidentTimelineDrawer.DrawScriptBuilderTimeline(g2d, incident);
344        }
345
346        if (focused)
347        {
348            CursorDrawer.DrawCursor(g2d, cursorTime, false);
349            if (this.getTopLevelAncestor() instanceof ScriptBuilderFrame)
350            {
351                if (((ScriptBuilderFrame) this.getTopLevelAncestor()).currentEventType != null)
352                {
353                    EventIconDrawer.DrawEventIcon(g2d,
354                            ((ScriptBuilderFrame) this.getTopLevelAncestor()).currentEventType,
355                            x + 5, y + 10);
356                }
357            }
358            if (this.getTopLevelAncestor() instanceof IncidentEditorFrame)
359            {
360                if (((IncidentEditorFrame) this.getTopLevelAncestor()).currentEventType != null)
361                {
362                    EventIconDrawer.DrawEventIcon(g2d,
363                            ((IncidentEditorFrame) this.getTopLevelAncestor()).currentEventType,
364                            x + 5, y + 10);
365                }
366            }
367        }
368    }
369
370    /**
371     * Local main for viewing this panel only.
372     *
373     * @author jdalbey
374     * @param args not used
375     */
376    public static void main(String[] args)
377    {
378        JFrame frame = new JFrame("ScriptBuilderTimelinePanel Demo");
379        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
380
381        IncidentTimelinePanel pnl = new IncidentTimelinePanel();
382
383        // Create a script
384        File inFile = new File("test/scriptbuilder/structures/test_input_file.xml");
385        SimulationScript script = new SimulationScript();
386        script.loadScriptFromFile(inFile);
387        // retrieve a single incident from the script
388        ScriptIncident inci = script.incidents.get(2);
389        // update this panel with an incident
390        pnl.timelinePanelUpdate(inci);
391
392        frame.getContentPane().add(pnl, BorderLayout.CENTER);
393        frame.pack();
394
395        frame.setVisible(true);
396
397    }
398}
Note: See TracBrowser for help on using the repository browser.