/[cits3200i]/trunk/UWAPlugins/PlaybackPlugin/Source/PlaybackControl.cs


UCC Code Repository

Diff of /trunk/UWAPlugins/PlaybackPlugin/Source/PlaybackControl.cs

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 61 by sebcw, Fri Sep 17 08:37:15 2010 UTC revision 62 by rvvs89, Thu Sep 30 03:22:02 2010 UTC
# Line 2  Line 2 
2  using System;  using System;
3  using System.Collections.Generic;  using System.Collections.Generic;
4  using System.ComponentModel;  using System.ComponentModel;
 using System.Drawing;  
5  using System.Data;  using System.Data;
6    using System.Drawing;
7  using System.Text;  using System.Text;
8  using System.Timers;  using System.Timers;
9  using System.Windows.Forms;  using System.Windows.Forms;
# Line 20  namespace PlaybackPlugin.Source Line 20  namespace PlaybackPlugin.Source
20          private PlaybackState state = PlaybackState.Disabled;          private PlaybackState state = PlaybackState.Disabled;
21          private IActivity activity = null;          private IActivity activity = null;
22          private System.Timers.Timer timer;          private System.Timers.Timer timer;
23            private DateTime startTime;
24            private DateTime endTime;
25            private DateTime currentTime;
26            private Nullable<DateTime> initialSelection = null;
27            private IRouteControl control;
28            private IRouteControlItem item;
29            private IGPSRoute route;
30            private EventHandler selectedItemsChangedHandler;
31            private IList<IRouteControlSelection> oldSelection;
32            private const double MOVE_SELECTION_THRESHOLD = 2000.0;
33            private const double PLAYBACKBAR_TICK_GRANULARITY = 100;
34            private const double REWIND_FACTOR = -5.0;
35            private const double FASTFORWARD_FACTOR = 5.0;
36            private const double STEP_SIZE = 1.0;
37    
38          public PlaybackControl()          public PlaybackControl()
39          {          {
40              InitializeComponent();              InitializeComponent();
41                if (PlaybackAnimationRouteControlLayer.Instances.Count == 0)
42                {
43                    // HACK: make designer work properly
44                    return;
45                }
46                CheckRouteValidity();
47                MarkSelectedRegion();
48              UpdateUI();              UpdateUI();
49              timer = new System.Timers.Timer(5000.0);              selectedItemsChangedHandler = new EventHandler(control_SelectedItemsChanged);
50                control.SelectedItemsChanged += selectedItemsChangedHandler;
51                timer = new System.Timers.Timer();
52                timer.Interval = 100.0;
53              timer.Elapsed += new ElapsedEventHandler(PlaybackTick);              timer.Elapsed += new ElapsedEventHandler(PlaybackTick);
54              timer.SynchronizingObject = this;              timer.SynchronizingObject = this;
55          }          }
56            
         public PlaybackControl(IActivity activity) : this()  
         {  
             this.activity = activity;  
         }  
   
57          public IActivity Activity          public IActivity Activity
58          {          {
59              get { return activity; }              get { return activity; }
60              set {              set {
61                  activity = value;                  activity = value;
62                  if (activity != null)                  State = activity == null ? PlaybackState.Disabled : PlaybackState.Stopped;
                 {  
                     State = PlaybackState.Stopped;  
                 }  
63              }              }
64          }          }
65    
# Line 58  namespace PlaybackPlugin.Source Line 74  namespace PlaybackPlugin.Source
74              }              }
75          }          }
76    
77            private DateTime CurrentTime
78            {
79                get { return currentTime; }
80                set
81                {
82                    currentTime = value;
83                    currentTime = DateTimeMax(currentTime, startTime);
84                    currentTime = DateTimeMin(currentTime, endTime);
85                    UpdateUI();
86                }
87            }
88    
89            public new void Dispose()
90            {
91                State = PlaybackState.Disabled;
92                control.SelectedItemsChanged -= selectedItemsChangedHandler;
93                control.SelectedItems = oldSelection;
94                timer.Stop();
95                timer.Dispose();
96                PlaybackAnimationRouteControlLayer.Instances[0].StartMarker.Visible = false;
97                PlaybackAnimationRouteControlLayer.Instances[0].EndMarker.Visible = false;
98                PlaybackAnimationRouteControlLayer.Instances[0].UpdateMarkers();
99                base.Dispose();
100            }
101    
102          private void UpdateUI()          private void UpdateUI()
103          {          {
104                TimeSpan length = endTime - startTime;
105                TimeSpan progress = currentTime - startTime;
106              rewindButton.Enabled = State != PlaybackState.Disabled && State != PlaybackState.Stopped;              rewindButton.Enabled = State != PlaybackState.Disabled && State != PlaybackState.Stopped;
107              fastForwardButton.Enabled = State != PlaybackState.Disabled && State != PlaybackState.Stopped;              fastForwardButton.Enabled = State != PlaybackState.Disabled && State != PlaybackState.Stopped;
108              playButton.Enabled = State != PlaybackState.Disabled;              playButton.Enabled = State != PlaybackState.Disabled;
# Line 69  namespace PlaybackPlugin.Source Line 112  namespace PlaybackPlugin.Source
112              speedSpinner.Enabled = State != PlaybackState.Disabled;              speedSpinner.Enabled = State != PlaybackState.Disabled;
113              statusStrip.Enabled = State != PlaybackState.Disabled;              statusStrip.Enabled = State != PlaybackState.Disabled;
114              playbackBar.Enabled = State != PlaybackState.Disabled;              playbackBar.Enabled = State != PlaybackState.Disabled;
115                playbackBar.Maximum = (int) (length.TotalMilliseconds / PLAYBACKBAR_TICK_GRANULARITY);
116                int ticks = Math.Min(playbackBar.Maximum, 10);
117                playbackBar.TickFrequency = playbackBar.Maximum / ticks;
118                playbackBar.Value = (int) (progress.TotalMilliseconds / PLAYBACKBAR_TICK_GRANULARITY);
119              statusLabel.Enabled = State != PlaybackState.Disabled;              statusLabel.Enabled = State != PlaybackState.Disabled;
120                statusLabel.Text = String.Format("{0}:{1:00}:{2:00} / {3}:{4:00}:{5:00}", progress.Hours, progress.Minutes, progress.Seconds, length.Hours, length.Minutes, length.Seconds);
121                control.SelectedItems = new List<IRouteControlSelection> { new PlaybackRouteControlSelection(item, currentTime) };
122                if (followButton.Checked)
123                {
124                    control.MapControl.Center = route.GetInterpolatedValue(currentTime).Value;
125                }
126          }          }
127    
128          public enum PlaybackState          private void CheckRouteValidity()
129          {          {
130              Disabled,              // TODO: Verify that the current route is one that can be played back (ie has valid time data)
131              Stopped,              // TODO: notify user that playback is impossible if the route does not have time data and throw exception
132              Paused,              control = PlaybackAnimationRouteControlLayer.Instances[0].Control;
133              Playing,              oldSelection = control.SelectedItems;
             FastForwarding,  
             Rewinding  
134          }          }
135    
136          private void playButton_Click(object sender, EventArgs e)          private static DateTime DateTimeMin(DateTime a, DateTime b)
137          {          {
138              State = State == PlaybackState.Playing || State == PlaybackState.FastForwarding || State == PlaybackState.Rewinding ? PlaybackState.Paused : PlaybackState.Playing;              return a < b ? a : b;
139          }          }
140    
141          private void fastForwardButton_Click(object sender, EventArgs e)          private static DateTime DateTimeMax(DateTime a, DateTime b)
142          {          {
143              State = State == PlaybackState.Playing || State == PlaybackState.FastForwarding || State == PlaybackState.Rewinding ? PlaybackState.FastForwarding : PlaybackState.FastForwarding;              return a > b ? a : b;
             // not done  
144          }          }
145    
146          private void rewindButton_Click(object sender, EventArgs e)          private static int RouteIndexFromDistance(IGPSRoute route, double distance)
147          {          {
148              State = State == PlaybackState.Playing || State == PlaybackState.FastForwarding || State == PlaybackState.Rewinding ? PlaybackState.Rewinding : PlaybackState.Rewinding;              // FIXME: add out parameter to output the remaining distance to improve accuracy
149              // not done              IEnumerator<ITimeValueEntry<IGPSPoint>> i = route.GetEnumerator();
150                int index = 0;
151                double count = 0.0;
152                i.MoveNext();
153                IGPSPoint prev = i.Current.Value;
154                while (i.MoveNext())
155                {
156                    IGPSPoint cur = i.Current.Value;
157                    count += prev.DistanceMetersToPoint(cur);
158                    if (count < distance)
159                    {
160                        index++;
161                        prev = cur;
162                    }
163                    else
164                    {
165                        return index;
166                    }
167                }
168                return index;
169          }          }
170    
171          private void loopButton_CheckedChanged(object sender, EventArgs e)          private static DateTime RouteTimeFromDistance(IGPSRoute route, double distance)
172          {          {
173              // TODO              int index = RouteIndexFromDistance(route, distance);
174                return route.StartTime.AddSeconds(route[index].ElapsedSeconds);
175          }          }
176    
177          private void speedSpinner_ValueChanged(object sender, EventArgs e)          private void CalculateSelectedRegion(out DateTime start, out DateTime end)
178          {          {
179              if ( speedSpinner.Value.Equals(1))              // FIXME: account for multiple ranges within one selection
180                start = DateTime.MaxValue;
181                end = DateTime.MinValue;
182                for (int k = 0; k < control.SelectedItems.Count; k++)
183                {
184                    IRouteControlSelection selection = control.SelectedItems[k];
185                    if (selection == null || !selection.Item.DisplayRoute || selection.Item.Item == null)
186                    {
187                        return;
188                    }
189                    if (selection.DistanceMetersRanges != null && selection.DistanceMetersRanges.Count >= 1)
190                    {
191                        start = DateTimeMin(start, RouteTimeFromDistance(route, selection.DistanceMetersRanges[0].Lower));
192                        end = DateTimeMax(end, RouteTimeFromDistance(route, selection.DistanceMetersRanges[0].Upper));
193                    }
194                    else if (selection.TimeRanges != null && selection.TimeRanges.Count >= 1)
195                    {
196                        start = DateTimeMin(start, selection.TimeRanges[0].Lower);
197                        end = DateTimeMax(start, selection.TimeRanges[0].Upper);
198                    }
199                }
200                if (start == DateTime.MaxValue)
201              {              {
202                  State = PlaybackState.Playing;                  start = DateTime.MinValue;
203              }              }
204                if (end == DateTime.MinValue)
205                {
206                    end = DateTime.MaxValue;
207                }
208            }
209    
210              decimal temp = speedSpinner.Value;          private void MarkSelectedRegion()
211              if (temp > 1)          {
212                item = control.Items[0];
213                route = item.Item.GPSRoute;
214                IList<IRouteControlSelection> selection = PlaybackAnimationRouteControlLayer.Instances[0].Control.SelectedItems;
215                CalculateSelectedRegion(out startTime, out endTime);
216                if (endTime == startTime)
217              {              {
218                  State = PlaybackState.FastForwarding;                  initialSelection = startTime;
219                    startTime = DateTime.MinValue;
220                    endTime = DateTime.MaxValue;
221              }              }
222                else
223                {
224                    initialSelection = null;
225                }
226                startTime = DateTimeMax(startTime, route.StartTime);
227                if (startTime > route.StartTime)
228                {
229                    MapMarker startMarker = PlaybackAnimationRouteControlLayer.Instances[0].StartMarker;
230                    startMarker.Location = route.GetInterpolatedValue(startTime).Value;
231                    startMarker.Visible = true;
232                }
233                endTime = DateTimeMin(endTime, route.StartTime.AddSeconds(route.TotalElapsedSeconds));
234                if (endTime < route.StartTime.AddSeconds(route.TotalElapsedSeconds))
235                {
236                    MapMarker endMarker = PlaybackAnimationRouteControlLayer.Instances[0].EndMarker;
237                    endMarker.Location = route.GetInterpolatedValue(endTime).Value;
238                    endMarker.Visible = true;
239                }
240                PlaybackAnimationRouteControlLayer.Instances[0].UpdateMarkers();
241                CurrentTime = initialSelection == null ? startTime : initialSelection.Value;
242            }
243    
244              if (temp == 0)          public enum PlaybackState
245            {
246                Disabled,
247                Stopped,
248                Paused,
249                Playing,
250                FastForwarding,
251                Rewinding
252            }
253    
254            private void playButton_Click(object sender, EventArgs e)
255            {
256                if (State == PlaybackState.Stopped && CurrentTime >= endTime)
257              {              {
258                  State = PlaybackState.Paused;                  CurrentTime = startTime;
259              }              }
260                State = State == PlaybackState.Playing || State == PlaybackState.FastForwarding || State == PlaybackState.Rewinding ? PlaybackState.Paused : PlaybackState.Playing;
261            }
262    
263              if (temp < 0)          private void fastForwardButton_Click(object sender, EventArgs e)
264            {
265                if (State == PlaybackState.Paused)
266              {              {
267                  State = PlaybackState.Rewinding;                  CurrentTime = CurrentTime.AddSeconds(STEP_SIZE);
268              }              }
269                                    else
270                                  {
271                    // TODO: implement fast-forward
272                }
273            }
274    
275              // TODO          private void rewindButton_Click(object sender, EventArgs e)
276            {
277                if (State == PlaybackState.Paused)
278                {
279                    CurrentTime = CurrentTime.AddSeconds(-STEP_SIZE);
280                }
281                else
282                {
283                    // TODO: implement rewind
284                }
285          }          }
286    
287          private void playbackBar_Scroll(object sender, EventArgs e)          private void playbackBar_Scroll(object sender, EventArgs e)
288          {          {
289              // TODO              CurrentTime = startTime.AddMilliseconds(playbackBar.Value * PLAYBACKBAR_TICK_GRANULARITY);
290          }          }
291    
292          private static int RouteIndexFromDistance(IEnumerator<ITimeValueEntry<IGPSPoint>> route, double distance)          private void PlaybackTick(object source, ElapsedEventArgs args)
293          {          {
294              int index = 0;              CurrentTime = CurrentTime.AddMilliseconds((double) speedSpinner.Value * timer.Interval);
295              double count = 0.0;              if (CurrentTime >= endTime)
             IGPSPoint prev = route.Current.Value;  
             while(route.MoveNext())  
296              {              {
297                  IGPSPoint cur = route.Current.Value;                  if (loopButton.Checked)
                 count += prev.DistanceMetersToPoint(cur);  
                 if(count < distance)  
298                  {                  {
299                      index++;                      CurrentTime = startTime;
300                                          prev = cur;                  }
301                  } else {                  else
302                      return index;                  {
303                                  }                      State = PlaybackState.Stopped;
304                    }
305              }              }
             return -1;  
306          }          }
307    
308          private void PlaybackTick(object source, ElapsedEventArgs args)          private void control_SelectedItemsChanged(object sender, EventArgs e)
309          {          {
310              //IRouteControlSelection selection = CollectionUtils.GetSingleItemOfType<IRouteControlSelection>(PlaybackAnimationRouteControlLayer.Instance.Control.SelectedItems);              // FIXME: account for multiple ranges within one selection
311              IRouteControlSelection selection = CollectionUtils.GetFirstItemOfType<IRouteControlSelection>(PlaybackAnimationRouteControlLayer.Selection);              DateTime selectedTime = DateTime.MinValue;
312              if (selection == null)              for (int k = 0; k < control.SelectedItems.Count; k++)
313                {
314                    IRouteControlSelection selection = control.SelectedItems[k];
315                    if (selection == null || !selection.Item.DisplayRoute || selection.Item.Item == null)
316                    {
317                        return;
318                    }
319                    if (selection.DistanceMetersRanges != null && selection.DistanceMetersRanges.Count >= 1)
320                    {
321                        selectedTime = RouteTimeFromDistance(route, selection.DistanceMetersRanges[0].Lower);
322                    }
323                    else if (selection.TimeRanges != null && selection.TimeRanges.Count >= 1)
324                    {
325                        selectedTime = selection.TimeRanges[0].Lower;
326                    }
327                    if (selectedTime != DateTime.MinValue)
328                    {
329                        break;
330                    }
331                }
332                if (selectedTime == DateTime.MinValue)
333              {              {
334                  // TODO                  return;
335              }              }
336              else              TimeSpan diff = currentTime < selectedTime ? selectedTime - currentTime : currentTime - selectedTime;
337                if (diff.TotalMilliseconds > MOVE_SELECTION_THRESHOLD)
338              {              {
339                  IList<IValueRange<DateTime>> ranges = selection.TimeRanges;                  CurrentTime = selectedTime;
                 IGPSRoute item = selection.Item.Item.GPSRoute;  
                 IList<IValueRange<double>> distanceRanges = selection.DistanceMetersRanges;  
                 /*DateTime upper = range.Upper;  
                 DateTime lower = range.Lower;*/  
                 Console.WriteLine("Test");  
340              }              }
341          }          }
342      }      }

Legend:
Removed from v.61  
changed lines
  Added in v.62

Managed by UCC Webmasters ViewVC Help
Powered by ViewVC 1.1.26