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 @ 18

Revision 18, 11.5 KB checked in by bmcguffin, 9 years ago (diff)

Resolved issue where a new event failed to be added to the incident when the user tried to add an event.

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