source: tmcsimulator-scriptbuilder/trunk/src/scriptbuilder/gui/panels/TimelineTickPanel.java @ 74

Revision 74, 8.8 KB checked in by jdalbey, 9 years ago (diff)

TimelineTickPanel?.java: Added a local main to display just this panel (as a unit test).

Line 
1package scriptbuilder.gui.panels;
2
3import java.awt.BorderLayout;
4import java.awt.Dimension;
5import java.awt.Graphics;
6import java.awt.Graphics2D;
7import java.awt.event.MouseEvent;
8import java.io.File;
9import javax.swing.JFrame;
10import javax.swing.JPanel;
11import javax.swing.event.MouseInputAdapter;
12import static junit.framework.Assert.assertEquals;
13import scriptbuilder.gui.IncidentEditorFrame;
14import scriptbuilder.gui.ScriptBuilderFrame;
15import scriptbuilder.gui.ScriptBuilderGuiConstants;
16import scriptbuilder.gui.drawers.EventIconDrawer;
17import scriptbuilder.structures.ScriptIncident;
18import scriptbuilder.structures.SimulationScript;
19
20/**
21 * Represents the underlying panel on the main timeline. All the
22 * IncidentTimelinePanel objects sit over it. This panel draws all the
23 * per-minute ticks on the timeline, and adjusts and scales them as necessary.
24 *
25 * @author Greg Eddington <geddingt@calpoly.edu>
26 * @author Bryan McGuffin
27 */
28public class TimelineTickPanel extends JPanel
29{
30
31    private int longestLength = ScriptBuilderGuiConstants.TICK_TIMELINE_SMALLEST_LENGTH;
32    private int x, y;
33    private boolean focused = false;
34
35    public void setZoom(float zoom)
36    {
37        repaint();
38    }
39
40    /**
41     * Listener for the mouse. Is notified when the mouse enters, exits, or
42     * moves around on the panel.
43     */
44    public class TimelineTickMouseListener extends MouseInputAdapter
45    {
46
47        /**
48         * When the mouse enters the panel, the panel gets focus.
49         *
50         * @param e the mouse event
51         */
52        @Override
53        public void mouseEntered(MouseEvent e)
54        {
55            focused = true;
56        }
57
58        /**
59         * When the mouse leaves the panel, the panel loses focus and refreshes.
60         *
61         * @param e the mouse event
62         */
63        @Override
64        public void mouseExited(MouseEvent e)
65        {
66            focused = false;
67            repaint();
68        }
69
70        /**
71         * When the mouse moves around in the panel, the panel refreshes and
72         * updates its mouse tracker.
73         *
74         * @param e
75         */
76        @Override
77        public void mouseMoved(MouseEvent e)
78        {
79            x = e.getX();
80            y = e.getY();
81
82            repaint();
83        }
84    }
85
86    /**
87     * Constructor. Set up the mouse listener.
88     */
89    public TimelineTickPanel()
90    {
91        super();
92
93        TimelineTickMouseListener mouseListener
94                = new TimelineTickMouseListener();
95        addMouseMotionListener(mouseListener);
96        addMouseListener(mouseListener);
97    }
98
99    /**
100     * Update the panel's dimensions based on number of events, zoom level, and
101     * which events are collapsed.
102     *
103     * @param script The main script model
104     */
105    public void update(SimulationScript script)
106    {
107        longestLength = ScriptBuilderGuiConstants.TICK_TIMELINE_SMALLEST_LENGTH;
108
109        // Get the stats on the incidents
110        int height = ScriptBuilderGuiConstants.TICK_TOP_MARGIN * 4;
111        for (ScriptIncident incident : script.incidents)
112        {
113            if (incident != null)
114            {
115                height += incident.collapsed
116                        ? ScriptBuilderGuiConstants.TIMELINE_OPENED_HEIGHT
117                        : ScriptBuilderGuiConstants.TIMELINE_OPENED_HEIGHT;
118                if ((incident.length + incident.offset) > longestLength)
119                {
120                    longestLength = incident.length + incident.offset;
121                }
122            }
123        }
124
125        Dimension newSize = new Dimension(longestLength
126                / ScriptBuilderGuiConstants.HORIZONTAL_TICK_RESOLUTION
127                * ScriptBuilderGuiConstants.PIXEL_WIDTH_PER_HORIZONTAL_TICK
128                + ScriptBuilderGuiConstants.TICK_TIMELINE_LEFT_MARGIN + 50,
129                height);
130        this.setPreferredSize(newSize);
131        this.setSize(newSize);
132
133        this.invalidate();
134    }
135
136    /**
137     * Update the panel's dimensions based on number of events, zoom level, and
138     * which events are collapsed.
139     *
140     * @param script The main script model
141     */
142    public void update(ScriptIncident incident)
143    {
144        longestLength = ScriptBuilderGuiConstants.TICK_TIMELINE_SMALLEST_LENGTH;
145
146        // Get the stats on the incidents
147        int height = ScriptBuilderGuiConstants.TICK_TOP_MARGIN * 4;
148
149        if (incident != null)
150        {
151            height += incident.collapsed
152                    ? ScriptBuilderGuiConstants.TIMELINE_OPENED_HEIGHT
153                    : ScriptBuilderGuiConstants.TIMELINE_OPENED_HEIGHT;
154            if ((incident.length + incident.offset) > longestLength)
155            {
156                longestLength = incident.length + incident.offset;
157            }
158
159        }
160
161        Dimension newSize = new Dimension(longestLength
162                / ScriptBuilderGuiConstants.HORIZONTAL_TICK_RESOLUTION
163                * ScriptBuilderGuiConstants.PIXEL_WIDTH_PER_HORIZONTAL_TICK
164                + ScriptBuilderGuiConstants.TICK_TIMELINE_LEFT_MARGIN + 50,
165                height);
166        this.setPreferredSize(newSize);
167        this.setSize(newSize);
168
169        this.invalidate();
170    }
171
172    /**
173     * Refresh the panel. Redraw the ticks based on zoom level, panel
174     * dimensions, and offset. If the user is trying to add an event, draw that
175     * event's icon under the mouse.
176     *
177     * @param g The graphics component
178     */
179    @Override
180    public void paint(Graphics g)
181    {
182        super.paint(g);
183
184        Graphics2D g2d = (Graphics2D) g;
185
186        // Draw the horizontal line
187        g2d.setFont(ScriptBuilderGuiConstants.TIMELINE_TICK_TIME_FONT);
188        g2d.setColor(ScriptBuilderGuiConstants.TIMELINE_TICK_COLOR);
189        g2d.fillRect(0, ScriptBuilderGuiConstants.TICK_TIMELINE_TOP_MARGIN,
190                longestLength, ScriptBuilderGuiConstants.TICK_TIMELINE_HEIGHT);
191
192        // Draw the ticks
193        int longestLengthPlusMargin = longestLength
194                / ScriptBuilderGuiConstants.HORIZONTAL_TICK_RESOLUTION
195                * ScriptBuilderGuiConstants.PIXEL_WIDTH_PER_HORIZONTAL_TICK
196                + ScriptBuilderGuiConstants.TICK_TIMELINE_LEFT_MARGIN;
197
198        // Minutes
199        g2d.setColor(ScriptBuilderGuiConstants.MINOR_TICK_COLOR);
200        int seconds = 0;
201        for (int i = ScriptBuilderGuiConstants.TICK_TIMELINE_LEFT_MARGIN;
202                i <= longestLengthPlusMargin;
203                i += ScriptBuilderGuiConstants.PIXEL_WIDTH_PER_HORIZONTAL_TICK, seconds += ScriptBuilderGuiConstants.HORIZONTAL_TICK_RESOLUTION)
204        {
205            g2d.drawLine(i, ScriptBuilderGuiConstants.TICK_TOP_MARGIN,
206                    i, ScriptBuilderGuiConstants.TICK_HEIGHT);
207        }
208
209        // Major Ticks
210        g2d.setColor(ScriptBuilderGuiConstants.TIMELINE_TICK_COLOR);
211        seconds = 0;
212        for (int i = ScriptBuilderGuiConstants.TICK_TIMELINE_LEFT_MARGIN;
213                i <= longestLengthPlusMargin;
214                i += ScriptBuilderGuiConstants.PIXEL_WIDTH_PER_HORIZONTAL_TICK
215                * ScriptBuilderGuiConstants.TICKS_PER_MAJOR_TICK, seconds += ScriptBuilderGuiConstants.HORIZONTAL_TICK_RESOLUTION
216                * ScriptBuilderGuiConstants.TICKS_PER_MAJOR_TICK)
217        {
218            g2d.drawLine(i, ScriptBuilderGuiConstants.TICK_TOP_MARGIN,
219                    i, ScriptBuilderGuiConstants.TICK_HEIGHT);
220
221        }
222
223        paintChildren(g);
224
225        if (this.getTopLevelAncestor() instanceof ScriptBuilderFrame)
226        {
227            if (focused
228                    && ((ScriptBuilderFrame) this.getTopLevelAncestor()).currentEventType != null)
229            {
230                EventIconDrawer.DrawEventIcon(g2d,
231                        ((ScriptBuilderFrame) this.getTopLevelAncestor()).currentEventType,
232                        x, y);
233            }
234        }
235        if (this.getTopLevelAncestor() instanceof IncidentEditorFrame)
236        {
237            if (focused
238                    && ((IncidentEditorFrame) this.getTopLevelAncestor()).currentEventType != null)
239            {
240                EventIconDrawer.DrawEventIcon(g2d,
241                        ((IncidentEditorFrame) this.getTopLevelAncestor()).currentEventType,
242                        x, y);
243            }
244        }
245    }
246
247    /**
248     * Local main for viewing this panel only.
249     *
250     * @author jdalbey
251     * @param args not used
252     */
253    public static void main(String[] args)
254    {
255        JFrame frame = new JFrame("FrameDemo");
256
257        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
258
259        TimelineTickPanel pnl = new TimelineTickPanel();
260        // Create a script
261        File inFile = new File("test/scriptbuilder/structures/test_input_file.xml");
262        SimulationScript instance = new SimulationScript();
263        instance.loadScriptFromFile(inFile);
264        // update this panel with the script
265        pnl.update(instance);
266        frame.getContentPane().add(pnl, BorderLayout.CENTER);
267        frame.setSize(300, 500);
268        frame.pack();
269
270        frame.setVisible(true);
271
272    }
273}
Note: See TracBrowser for help on using the repository browser.