00001 using System;
00002 using System.Collections.Generic;
00003 using System.ComponentModel;
00004 using System.Drawing;
00005 using System.Data;
00006 using System.Text;
00007 using System.Windows.Forms;
00008 using DXGfxLib;
00009
00010 namespace Editor
00011 {
00012 public class Marker
00013 {
00014 public Point position;
00015 public DXGfxLib.Event evt;
00016 }
00017
00018 public partial class TimeLineView : UserControl
00019 {
00020
00021 Font drawFont = new Font("Arial", 6);
00022 SolidBrush drawBrush = new SolidBrush(Color.Black);
00023 Pen drawPen = new Pen(Color.Black);
00024 Pen boldPen = new Pen(Color.Black, 2);
00025
00026 private double startTime = 0;
00027 private double endTime = 30;
00028
00029 private int middle;
00030
00031 private List<Marker> markers;
00032
00033 private Marker selectedMarker = null;
00034
00035 private Mediator mediator = null;
00036
00037 public TimeLineView(Mediator mediator)
00038 {
00039 InitializeComponent();
00040
00041 markers = new List<Marker>();
00042
00043 this.mediator = mediator;
00044
00045 mediator.OnSelect += new Select(mediator_OnSelect);
00046 }
00047
00048 void mediator_OnSelect(string name, object obj)
00049 {
00050 TimeLine timeLine = null;
00051
00052 SceneObject sObj = obj as SceneObject;
00053 DXGfxLib.Scene scene = obj as DXGfxLib.Scene;
00054
00055 if(sObj!=null)
00056 {
00057 timeLine = sObj.GetTimeLine();
00058 }
00059 else if(scene!=null)
00060 {
00061 timeLine = scene.GetTimeLine();
00062 }
00063 UpdateTimeLineView(timeLine);
00064
00065 Refresh();
00066 }
00067
00068 private void TimeLineView_Paint(object sender, PaintEventArgs e)
00069 {
00070 middle = (int)Math.Floor(0.5f * e.Graphics.VisibleClipBounds.Height);
00071 UpdateMarkerPositions();
00072
00073 MakeAxesAndGrid(e.Graphics);
00074 DisplayMarkers(e.Graphics);
00075 }
00076
00077 public void SetStartAndEnd(double startTime, double endTime)
00078 {
00079 this.startTime = startTime;
00080 this.endTime = endTime;
00081 }
00082
00083 public void GetStartAndEnd(out double startTime, out double endTime)
00084 {
00085 startTime = this.startTime;
00086 endTime = this.endTime;
00087 }
00088
00089 private void MakeAxesAndGrid(Graphics g)
00090 {
00091 Point leftMid = new Point(0, (int)Math.Ceiling(0.5f * g.VisibleClipBounds.Height));
00092 Point rightMid = new Point((int)Math.Ceiling(g.VisibleClipBounds.Width), (int)Math.Ceiling(0.5f * g.VisibleClipBounds.Height));
00093 g.DrawLine(new Pen(Color.Black), leftMid, rightMid);
00094
00095 MakeVerticalGraduations(g, startTime, endTime, 5);
00096 }
00097
00098 private void MakeVerticalGraduations(Graphics g, double startTime, double endTime, int numberOfGrads)
00099 {
00100 Point high = new Point(0, 20);
00101 Point low = new Point(0, Height-10);
00102
00103 int pace = (int)Math.Floor((g.VisibleClipBounds.Width - 10) / numberOfGrads);
00104
00105 double timePace = (endTime - startTime) / numberOfGrads;
00106 double timeCurrent = startTime;
00107
00108 for (int i = 0; i < numberOfGrads; i++)
00109 {
00110 high.X = i*pace + 10;
00111 low.X = high.X;
00112
00113 g.DrawLine(drawPen, high, low);
00114 g.DrawString(timeCurrent.ToString(), drawFont, drawBrush, new PointF(low.X , low.Y));
00115
00116 timeCurrent += timePace;
00117 }
00118 }
00119
00120 private void DisplayMarkers(Graphics g)
00121 {
00122 foreach (Marker marker in markers)
00123 {
00124
00125
00126 Point[] points = new Point[3];
00127 points[0] = new Point(marker.position.X, middle + 2);
00128 points[1] = new Point(marker.position.X - 6, middle + 8);
00129 points[2] = new Point(marker.position.X + 6, middle + 8);
00130
00131 Pen pen = null;
00132 if (marker == selectedMarker)
00133 {
00134 pen = boldPen;
00135 }
00136 else
00137 {
00138 pen = drawPen;
00139 }
00140 g.DrawPolygon(pen, points);
00141
00142 g.DrawString(marker.evt.name, drawFont, drawBrush, new PointF(marker.position.X - 5, middle + 10));
00143 }
00144 }
00145
00146 protected override void OnMouseDoubleClick(MouseEventArgs e)
00147 {
00148
00149
00150 Point position = new Point(e.X, e.Y);
00151
00152 Marker testMarker = Select(position, 6);
00153
00154 if (testMarker != null)
00155 {
00156 EditEvent(testMarker);
00157 }
00158 else
00159 {
00160 CreateEvent(position);
00161 }
00162 this.Refresh();
00163 }
00164
00165 protected void EditEvent(Marker marker)
00166 {
00167 NewEventDialog dlg = new NewEventDialog();
00168
00169 dlg.name = marker.evt.name;
00170 dlg.type = marker.evt.type;
00171 dlg.value = marker.evt.value;
00172
00173 if (dlg.ShowDialog() == DialogResult.OK)
00174 {
00175 marker.evt.name = dlg.name;
00176 marker.evt.type = dlg.type;
00177 marker.evt.value = dlg.value;
00178
00179 selectedMarker = marker;
00180 }
00181 else
00182 {
00183 return;
00184 }
00185
00186 if (mediator.selectedScriptableObj != null)
00187 {
00188 UpdateScriptableObjectTimeLine(mediator.selectedScriptableObj);
00189 }
00190 else
00191 {
00192 throw new NullReferenceException("This is bad, I don't expect to end up here!");
00193 }
00194 }
00195
00196 protected void CreateEvent(Point p)
00197 {
00198 NewEventDialog dlg = new NewEventDialog();
00199
00200 if (dlg.ShowDialog() == DialogResult.OK)
00201 {
00202 Marker marker = new Marker();
00203
00204 marker.position = p;
00205
00206 DXGfxLib.Event evt = new DXGfxLib.Event();
00207 evt.name = dlg.name;
00208 evt.timeOffset = (float)(p.X * ((endTime - startTime) / this.Width));
00209 evt.type = dlg.type;
00210 evt.value = dlg.value;
00211
00212 marker.evt = evt;
00213
00214 markers.Add(marker);
00215 selectedMarker = marker;
00216 }
00217 else
00218 {
00219 return;
00220 }
00221
00222 if (mediator.selectedScriptableObj != null)
00223 {
00224 UpdateScriptableObjectTimeLine(mediator.selectedScriptableObj);
00225 }
00226 else
00227 {
00228 throw new NullReferenceException("This is bad, I don't expect to end up here!");
00229 }
00230 }
00231
00232 protected override void OnMouseClick(MouseEventArgs e)
00233 {
00234 Point click = new Point(e.X, e.Y);
00235 Marker tmpMarker = Select(click, 15);
00236
00237 if (tmpMarker == null)
00238 {
00239 return;
00240 }
00241
00242 selectedMarker = tmpMarker;
00243
00244 this.Refresh();
00245 }
00246
00247 public Marker Select(Point p, double maxDist)
00248 {
00249 Marker res = null;
00250
00251 double dist = maxDist;
00252 double tmpDist = maxDist;
00253
00254 foreach (Marker marker in markers)
00255 {
00256 tmpDist = Distance(marker.position, p);
00257 if (tmpDist < dist)
00258 {
00259 dist = tmpDist;
00260 res = marker;
00261 }
00262 }
00263
00264 return res;
00265 }
00266
00267 public Marker[] Pick(Point p)
00268 {
00269 List<Marker> res = new List<Marker>();
00270
00271 foreach (Marker marker in markers)
00272 {
00273 if (Distance(marker.position, p) < 6)
00274 {
00275 res.Add(marker);
00276 }
00277 }
00278
00279 return res.ToArray();
00280 }
00281
00282 public double Distance(Point p0, Point p1)
00283 {
00284 return Math.Sqrt(Math.Pow(p0.X - p1.X, 2) + Math.Pow(p0.Y - p1.Y, 2));
00285 }
00286
00287 protected override void OnKeyDown(KeyEventArgs e)
00288 {
00289 if (e.KeyCode == Keys.Delete)
00290 {
00291 if (selectedMarker != null)
00292 {
00293 SuppresMarker(selectedMarker);
00294 selectedMarker = null;
00295 Refresh();
00296 }
00297 }
00298 }
00299
00300 public void SuppresMarker(Marker marker)
00301 {
00302 bool success = markers.Remove(marker);
00303 }
00304
00305 public void UpdateScriptableObjectTimeLine(IAmScriptable scriptableObj)
00306 {
00307 DXGfxLib.TimeLine timeLine = scriptableObj.GetTimeLine();
00308
00309 timeLine.Clear();
00310
00311 foreach (Marker marker in markers)
00312 {
00313 timeLine.events.Add(marker.evt);
00314 }
00315 }
00316
00317 public void UpdateTimeLineView(TimeLine timeLine)
00318 {
00319 markers.Clear();
00320
00321 if ((timeLine != null) && (timeLine.events.Count > 0))
00322 {
00323 foreach (Event evt in timeLine.events)
00324 {
00325 Marker tmpMarker = new Marker();
00326 tmpMarker.position.X = PosFromTime(evt.timeOffset);
00327
00328 tmpMarker.evt = evt;
00329
00330 markers.Add(tmpMarker);
00331 }
00332 }
00333 Refresh();
00334 }
00335
00336 public void UpdateMarkerPositions()
00337 {
00338 foreach(Marker marker in markers)
00339 {
00340 marker.position.X = PosFromTime(marker.evt.timeOffset);
00341 marker.position.Y = middle + 2;
00342 }
00343 }
00344
00345 public int PosFromTime(float time)
00346 {
00347 return (int)Math.Floor((time - startTime) * (Width / (endTime - startTime)));
00348 }
00349 }
00350 }