Aggiunta gestione bestlap e lastlap sul monitor.
[toni-reis.git] / src / simulator-monitor-gui.adb
blobbbeb98b69e79457c0aee83635d389ffc636a85cd
1 with Ada.Text_IO; use Ada.Text_IO;
2 with Ada.Float_Text_IO; use Ada.Float_Text_IO;
3 with Ada.Calendar.Formatting;
5 with Glib; use Glib;
6 with Gtk.Main; use Gtk.Main;
7 with Gtk; use Gtk;
8 with Gdk.Event; use Gdk.Event;
9 with Gdk.Types; use Gdk.Types;
10 with Gtk.Enums; use Gtk.Enums;
11 with Gdk.Threads; use Gdk.Threads;
12 with Gtkada.Dialogs; use Gtkada.Dialogs;
14 with Simulator.Statistics; use Simulator.Statistics;
16 package body Simulator.Monitor.Gui is
17 package DurationIO is new Ada.Text_IO.Fixed_Io(Duration);
19 function Delete_Event (Widget : access Gtk_Widget_Record'Class; Event : Gdk_Event) return Boolean
21 pragma Unreferenced (Event);
22 pragma Unreferenced (Widget);
23 begin
24 Simulator.Monitor.Quit;
25 Gtk.Main.Main_Quit;
26 Put_Line ("GUI: delete event occurred");
27 return False;
28 end Delete_Event;
30 procedure Destroy (Widget : access Gtk_Widget_Record'Class) is
31 pragma Unreferenced (Widget);
32 begin
33 Gtk.Main.Gtk_Exit(0);
34 end Destroy;
37 procedure Gtk_New (Monitor : out Monitor_Access) is
38 begin
39 Monitor := new Monitor_Record;
40 Ref := Monitor;
41 Simulator.Monitor.Gui.Initialize (Monitor);
42 end Gtk_New;
44 procedure Initialize (Monitor : access Monitor_Record'Class) is
45 pragma Suppress (All_Checks);
46 Pixmaps_Dir : constant String := "pixmaps/";
47 Num : Gint;
48 begin
49 Gtk.Window.Initialize (Monitor, Window_Toplevel);
50 Set_Border_Width (Monitor, 2);
51 Set_Title (Monitor, "Monitor");
52 Set_Position (Monitor, Win_Pos_None);
53 Set_Modal (Monitor, False);
54 Set_Resizable (Monitor, True);
56 -- collego i segnali per la chiusura dell'applicazione
57 Return_Handlers.Connect(Monitor, "delete_event", Return_Handlers.To_Marshaller (Delete_Event'Access));
58 Handlers.Connect(Monitor, "destroy", Handlers.To_Marshaller (Destroy'Access));
60 Gtk_New_Vbox (Monitor.Vbox2, False, 5);
61 Gtk_New_Hbox (Monitor.Hbox1, False, 5);
63 Gtk_New (Monitor.Frame1);
64 Set_Label_Align (Monitor.Frame1, 0.0, 0.5);
65 Set_Shadow_Type (Monitor.Frame1, Shadow_Etched_In);
67 Gtk_New
68 (Monitor.Alignment1, 0.5, 0.5, 1.0, 1.0);
69 Set_Border_Width (Monitor.Alignment1, 5);
71 Gtk_New (Monitor.Scrolledwindow1);
72 Set_Policy (Monitor.Scrolledwindow1, Policy_Automatic, Policy_Automatic);
73 Set_Shadow_Type (Monitor.Scrolledwindow1, Shadow_In);
74 Set_Placement (Monitor.Scrolledwindow1, Corner_Top_Left);
76 -- Creo il modello dati per la classifica
77 Gtk_New (Monitor.Model1,
78 (0 => GType_Int, -- Pos
79 1 => GType_Int, -- Id
80 2 => GType_Int, -- Lap
81 3 => GType_Int, -- Intermediate
82 4 => GType_String, -- Colore
83 5 => GType_String, -- Best Lap
84 6 => GType_String -- Last Lap
85 ));
87 Gtk_New_With_Model (Monitor.Model1_Sort, Monitor.Model1);
89 Gtk_New (Monitor.Treeview1, Monitor.Model1_Sort);
90 Set_Sort_Column_Id (+(Monitor.Model1_Sort), 0 , Sort_Ascending);
91 Gtk_New(Monitor.Col);
92 Gtk_New(Monitor.Text_R);
93 Set_Title (Monitor.Col, "Pos");
94 Num := Append_Column (Monitor.Treeview1, Monitor.Col);
95 Pack_Start (Monitor.Col, Monitor.Text_R, True);
96 Add_Attribute (Monitor.Col, Monitor.Text_R, "text", 0);
98 Gtk_New(Monitor.Col);
99 Gtk_New(Monitor.Text_R);
100 Set_Title (Monitor.Col, "Id");
101 Num := Append_Column (Monitor.Treeview1, Monitor.Col);
102 Pack_Start (Monitor.Col, Monitor.Text_R, True);
103 Add_Attribute (Monitor.Col, Monitor.Text_R, "text", 1);
104 Add_Attribute (Monitor.Col, Monitor.Text_R, "background", 4);
106 Gtk_New(Monitor.Col);
107 Gtk_New(Monitor.Text_R);
108 Set_Title (Monitor.Col, "Lap");
109 Num := Append_Column (Monitor.Treeview1, Monitor.Col);
110 Pack_Start (Monitor.Col, Monitor.Text_R, True);
111 Add_Attribute (Monitor.Col, Monitor.Text_R, "text", 2);
113 Gtk_New(Monitor.Col);
114 Gtk_New(Monitor.Text_R);
115 Set_Title (Monitor.Col, "Int");
116 Num := Append_Column (Monitor.Treeview1, Monitor.Col);
117 Pack_Start (Monitor.Col, Monitor.Text_R, True);
118 Add_Attribute (Monitor.Col, Monitor.Text_R, "text", 3);
120 Gtk_New(Monitor.Col);
121 Gtk_New(Monitor.Text_R);
122 Set_Title (Monitor.Col, "Best Lap");
123 Num := Append_Column (Monitor.Treeview1, Monitor.Col);
124 Pack_Start (Monitor.Col, Monitor.Text_R, True);
125 Add_Attribute (Monitor.Col, Monitor.Text_R, "text", 5);
127 Gtk_New(Monitor.Col);
128 Gtk_New(Monitor.Text_R);
129 Set_Title (Monitor.Col, "Last Lap");
130 Num := Append_Column (Monitor.Treeview1, Monitor.Col);
131 Pack_Start (Monitor.Col, Monitor.Text_R, True);
132 Add_Attribute (Monitor.Col, Monitor.Text_R, "text", 6);
134 Set_Headers_Visible (Monitor.Treeview1, True);
135 Set_Rules_Hint (Monitor.Treeview1, True);
136 Set_Reorderable (Monitor.Treeview1, False);
137 Set_Enable_Search (Monitor.Treeview1, False);
139 Add (Monitor.Scrolledwindow1, Monitor.Treeview1);
140 Add (Monitor.Alignment1, Monitor.Scrolledwindow1);
141 Add (Monitor.Frame1, Monitor.Alignment1);
142 Gtk_New (Monitor.Label1, "Ranking");
143 Set_Alignment (Monitor.Label1, 0.5, 0.5);
144 Set_Padding (Monitor.Label1, 0, 0);
145 Set_Justify (Monitor.Label1, Justify_Left);
146 Set_Line_Wrap (Monitor.Label1, False);
147 Set_Selectable (Monitor.Label1, False);
148 Set_Use_Markup (Monitor.Label1, True);
149 Set_Use_Underline (Monitor.Label1, False);
150 Set_Label_Widget (Monitor.Frame1,Monitor.Label1);
152 Pack_Start
153 (Monitor.Hbox1,
154 Monitor.Frame1,
155 Expand => True,
156 Fill => True,
157 Padding => 5);
158 Gtk_New (Monitor.Frame2);
159 Set_Label_Align (Monitor.Frame2, 0.0, 0.5);
160 Set_Shadow_Type (Monitor.Frame2, Shadow_Etched_In);
162 Gtk_New
163 (Monitor.Alignment2, 0.5, 0.5, 1.0, 1.0);
164 Set_Border_Width (Monitor.Alignment2, 5);
166 Gtk_New (Monitor.Scrolledwindow2);
167 Set_Policy (Monitor.Scrolledwindow2, Policy_Automatic, Policy_Automatic);
168 Set_Shadow_Type (Monitor.Scrolledwindow2, Shadow_In);
169 Set_Placement (Monitor.Scrolledwindow2, Corner_Top_Left);
171 -- Creo il modello dati per gli intertempi
172 Gtk_New (Monitor.Model2,
173 (0 => GType_Int, -- Pos
174 1 => GType_Int, -- Id
175 2 => GType_String, -- Distacco
176 3 => GType_String -- Velocita'
179 Gtk_New (Monitor.Treeview2, Monitor.Model2);
180 Set_Size_Request (Monitor.Treeview2, 250, 250);
181 Gtk_New(Monitor.Col);
182 Gtk_New(Monitor.Text_R);
183 Set_Title (Monitor.Col, "Pos");
184 Num := Append_Column (Monitor.Treeview2, Monitor.Col);
185 Pack_Start (Monitor.Col, Monitor.Text_R, True);
186 Add_Attribute (Monitor.Col, Monitor.Text_R, "text", 0);
188 Gtk_New(Monitor.Col);
189 Gtk_New(Monitor.Text_R);
190 Set_Title (Monitor.Col, "Id");
191 Num := Append_Column (Monitor.Treeview2, Monitor.Col);
192 Pack_Start (Monitor.Col, Monitor.Text_R, True);
193 Add_Attribute (Monitor.Col, Monitor.Text_R, "text", 1);
195 Gtk_New(Monitor.Col);
196 Gtk_New(Monitor.Text_R);
197 Set_Title (Monitor.Col, "Time");
198 Num := Append_Column (Monitor.Treeview2, Monitor.Col);
199 Pack_Start (Monitor.Col, Monitor.Text_R, True);
200 Add_Attribute (Monitor.Col, Monitor.Text_R, "text", 2);
202 Gtk_New(Monitor.Col);
203 Gtk_New(Monitor.Text_R);
204 Set_Title (Monitor.Col, "Vel");
205 Num := Append_Column (Monitor.Treeview2, Monitor.Col);
206 Pack_Start (Monitor.Col, Monitor.Text_R, True);
207 Add_Attribute (Monitor.Col, Monitor.Text_R, "text", 3);
209 Gtk_New_Vbox (Monitor.Vbox1, False, 0);
210 Gtk_New_Hbox (Monitor.Hbox2, False, 0);
212 Gtk_New (Monitor.Int_Info, "Lap: -- Intermediate: --");
213 Set_Alignment (Monitor.Int_Info, 0.0, 0.5);
214 Set_Padding (Monitor.Int_Info, 0, 0);
215 Set_Justify (Monitor.Int_Info, Justify_Left);
216 Set_Line_Wrap (Monitor.Int_Info, False);
217 Set_Selectable (Monitor.Int_Info, False);
218 Set_Use_Markup (Monitor.Int_Info, False);
219 Set_Use_Underline (Monitor.Int_Info, False);
221 Pack_Start
222 (Monitor.Hbox2,
223 Monitor.Int_Info,
224 Expand => True,
225 Fill => True,
226 Padding => 0);
228 -- Bottone Lock Statistics
229 Gtk_New (Monitor.Lock, "Lock");
230 -- callback del tasto Lock
231 Handlers.Connect(Monitor.Lock, "clicked", Handlers.To_Marshaller (ToggleLock'Access));
233 Pack_Start
234 (Monitor.Hbox2,
235 Monitor.Lock,
236 Expand => False,
237 Fill => False,
238 Padding => 0);
240 Pack_Start
241 (Monitor.Vbox1,
242 Monitor.Hbox2,
243 Expand => False,
244 Fill => False,
245 Padding => 0);
247 Set_Headers_Visible (Monitor.Treeview2, True);
248 Set_Rules_Hint (Monitor.Treeview2, True);
249 Set_Reorderable (Monitor.Treeview2, True);
250 Set_Enable_Search (Monitor.Treeview2, False);
252 Add (Monitor.Scrolledwindow2, Monitor.Treeview2);
253 Add (Monitor.Alignment2, Monitor.VBox1);
255 Pack_Start
256 (Monitor.Vbox1,
257 Monitor.Scrolledwindow2,
258 Expand => True,
259 Fill => True,
260 Padding => 0);
262 Add (Monitor.Frame2, Monitor.Alignment2);
263 Gtk_New (Monitor.Label2, "Statistics");
264 Set_Alignment (Monitor.Label2, 0.5, 0.5);
265 Set_Padding (Monitor.Label2, 0, 0);
266 Set_Justify (Monitor.Label2, Justify_Left);
267 Set_Line_Wrap (Monitor.Label2, False);
268 Set_Selectable (Monitor.Label2, False);
269 Set_Use_Markup (Monitor.Label2, True);
270 Set_Use_Underline (Monitor.Label2, False);
271 Set_Label_Widget (Monitor.Frame2,Monitor.Label2);
273 Pack_Start
274 (Monitor.Hbox1,
275 Monitor.Frame2,
276 Expand => False,
277 Fill => True,
278 Padding => 5);
280 Gtk_New (Monitor.Frame3);
281 Set_Label_Align (Monitor.Frame3, 0.0, 0.5);
282 Set_Shadow_Type (Monitor.Frame3, Shadow_Etched_In);
284 Gtk_New
285 (Monitor.Alignment3, 0.5, 0.5, 1.0, 1.0);
286 Set_Border_Width (Monitor.Alignment3, 5);
288 Add (Monitor.Frame3, Monitor.Alignment3);
289 Gtk_New (Monitor.Label3, "Record");
290 Set_Alignment (Monitor.Label3, 0.5, 0.5);
291 Set_Padding (Monitor.Label3, 0, 0);
292 Set_Justify (Monitor.Label3, Justify_Left);
293 Set_Line_Wrap (Monitor.Label3, False);
294 Set_Selectable (Monitor.Label3, False);
295 Set_Use_Markup (Monitor.Label3, True);
296 Set_Use_Underline (Monitor.Label3, False);
297 Set_Label_Widget (Monitor.Frame3,Monitor.Label3);
299 Gtk_New_Hbox (Monitor.Hbox3, False, 0);
301 Gtk_New (Monitor.BestLap_Info, "Best Lap: -- : -- : --- Car: -- on lap --");
302 Set_Alignment (Monitor.BestLap_Info, 0.0, 0.5);
304 Gtk_New (Monitor.MaxSpeed_Info, "Max Speed: ---,-- km/h Car: --");
305 Set_Alignment (Monitor.MaxSpeed_Info, 0.0, 0.5);
307 Pack_Start
308 (Monitor.Hbox3,
309 Monitor.BestLap_Info,
310 Expand => True,
311 Fill => True,
312 Padding => 5);
314 Pack_Start
315 (Monitor.Hbox3,
316 Monitor.MaxSpeed_Info,
317 Expand => True,
318 Fill => True,
319 Padding => 5);
321 Add (Monitor.Alignment3, Monitor.HBox3);
323 Pack_Start
324 (Monitor.Vbox2,
325 Monitor.Hbox1,
326 Expand => True,
327 Fill => True,
328 Padding => 5);
330 Pack_Start
331 (Monitor.Vbox2,
332 Monitor.Frame3,
333 Expand => False,
334 Fill => False,
335 Padding => 5);
337 Add (Monitor, Monitor.Vbox2);
338 Set_Size_Request (Monitor, 600, 350);
339 end Initialize;
341 procedure Update_Model (Pos: Positive;
342 CarId: CarId_T;
343 Lap: Natural;
344 Intermediate: Natural;
345 WakeupTime: Duration;
346 Vel: Float;
347 LastLap : Duration;
348 BestLap: Duration) is
349 Iter : Gtk_Tree_Iter;
350 Iter1: Gtk_Tree_Iter;
351 OldPos : Positive;
352 StrTime : String := "tttttttttt";
353 StrVel : String := "vvvvvvvv";
354 m : Integer;
355 s : Integer;
356 c : Integer;
357 begin
358 Gdk.Threads.Enter;
359 -- disabilito ordinamento automatico
361 -- Put_Line("Update gui-monitor's data. Id: " & CarId'Img & ", Pos: " & Pos'Img & ".");
362 -- cerco riga auto
363 Iter := Get_Iter_First(Ref.Model1);
364 while (Iter /= Null_Iter and then Get_Int(Ref.Model1, Iter, 1) /= GInt(CarId)) loop
365 Next(Ref.Model1, Iter);
366 end loop;
368 -- aggiorno dati
369 if (Iter /= Null_Iter) then
370 -- aggiorno i valori
371 OldPos := Positive(Get_Int(Ref.Model1, Iter, 0));
372 Set (Ref.Model1, Iter, 0, GInt(Pos));
373 Set (Ref.Model1, Iter, 1, GInt(CarId));
374 Set (Ref.Model1, Iter, 2, GInt(Lap));
375 Set (Ref.Model1, Iter, 3, GInt(Intermediate));
376 if (BestLap /= Duration'Last) then
377 m := Integer(Float'Truncation(Float(BestLap)/60.0));
378 s := Integer(Float'Truncation(Float(BestLap))) - m*60;
379 c := Integer(Float'Truncation(Float(BestLap * 1000))) - m*60000 -s *1000;
380 Set (Ref.Model1, Iter, 5, m'Img & ":" & s'Img & ":" & c'Img);
381 else
382 Set (Ref.Model1, Iter, 5, "--");
383 end if;
384 if (LastLap /= Duration'Last) then
385 m := Integer(Float'Truncation(Float(LastLap)/60.0));
386 s := Integer(Float'Truncation(Float(LastLap))) - m*60;
387 c := Integer(Float'Truncation(Float(LastLap * 1000))) - m*60000 -s *1000;
388 Set (Ref.Model1, Iter, 6, m'Img & ":" & s'Img & ":" & c'Img);
389 else
390 Set (Ref.Model1, Iter, 6, "--");
391 end if;
393 if( Pos - OldPos = 0) then
394 ChangePosition(CarId) := 0;
395 else
396 ChangePosition(CarId) :=ChangePosition(CarId)+ Pos - OldPos;
397 end if;
399 Put_Line("Posizione auto "&CarId'Img&" cambiata di: "&ChangePosition(CarId)'Img);
400 -- if (Pos < OldPos) then
401 -- coloro di verde la posizione
402 if (ChangePosition(CarId) < 0) then
403 Set (Ref.Model1, Iter, 4, "light green");
404 else
405 Set (Ref.Model1, Iter, 4, "white");
406 end if;
408 -- Aggiorno le posizioni delle macchine coinvolte nel sorpasso
409 Iter := Get_Iter_First(Ref.Model1);
411 while( Iter /= Null_Iter) loop
412 if (Get_Int(Ref.Model1, Iter, 0) >= GInt(Pos) and then Get_Int(Ref.Model1, Iter, 0) < GInt(OldPos) and then Get_Int(Ref.Model1, Iter, 1) /= GInt(CarId)) then
413 Set (Ref.Model1, Iter, 0, GInt(Get_Int(Ref.Model1, Iter, 0)+1));
414 -- aggiorno cambio posizioni e coloro
415 ChangePosition(CarId_T(Get_Int(Ref.Model1, Iter, 1))) := ChangePosition(CarId_T(Get_Int(Ref.Model1, Iter, 1))) +1;
416 if ( ChangePosition(CarId_T(Get_Int(Ref.Model1, Iter, 1)))< 0) then
417 -- coloro di verde la posizione
418 Set (Ref.Model1, Iter, 4, "light green");
419 elsif ( ChangePosition(CarId_T(Get_Int(Ref.Model1, Iter, 1)))= 0) then
420 Set (Ref.Model1, Iter, 4, "white");
421 else
422 Set (Ref.Model1, Iter, 4, "red");
423 end if;
424 else
425 null;
426 end if;
427 Next(Ref.Model1, Iter);
428 end loop;
429 else
430 -- appendo in fondo alla lista
431 Put_Line("Aggiungo a monitor Id: " & CarId'Img & ", Pos: " & Pos'Img & ".");
432 Append(Ref.Model1, Iter);
433 Set (Ref.Model1, Iter, 0, GInt(Pos));
434 Set (Ref.Model1, Iter, 1, GInt(CarId));
435 Set (Ref.Model1, Iter, 2, GInt(Lap));
436 Set (Ref.Model1, Iter, 3, GInt(Intermediate));
437 Set (Ref.Model1, Iter, 4, "white");
438 Set (Ref.Model1, Iter, 5, "--");
439 Set (Ref.Model1, Iter, 6, "--");
440 end if;
442 -- aggiorno i valori massimi
443 if ((Lap > Ref.LastLap or ((Lap = Ref.LastLap) and (Intermediate > Ref.LastInt))) and Ref.Observing = False) then
444 Ref.LastLap := Lap;
445 Ref.LastInt := Intermediate;
446 Ref.LastTime := WakeupTime;
447 Set_Text(Ref.Int_Info, "Lap: "&Ref.LastLap'Img&" Intermediate: "&Ref.LastInt'Img);
449 -- e pulisco le statistiche
450 Clear(Ref.Model2);
451 end if;
453 -- se giro e settore giusto aggiungo a statistics
454 if ((Lap = Ref.LastLap) and (Intermediate = Ref.LastInt)) then
455 -- Put_Line("Aggiungo a monitor di destra Id: " & CarId'Img & ", Pos: " & Pos'Img & ".");
456 Insert(Ref.Model2, Iter, GInt(Pos)-1);
457 --Append(Ref.Model2, Iter);
458 Set (Ref.Model2, Iter, 0, GInt(Pos));
459 Set (Ref.Model2, Iter, 1, GInt(CarId));
460 if (Pos = 1) then
461 StrTime := " -- ";
462 Set (Ref.Model2, Iter, 2, " "&StrTime&" ");
463 else
464 DurationIO.Put(StrTime, (WakeupTime - Ref.LastTime), Aft => 3);
465 Set (Ref.Model2, Iter, 2, "+ "&StrTime&" s");
466 end if;
467 Put(StrVel, Vel*3.6, Aft => 2, Exp => 0);
468 Set (Ref.Model2, Iter, 3, StrVel&" km/h");
469 --aggiunto per prova
470 Next(Ref.Model2, Iter);
471 while (Iter /= Null_Iter) loop
473 Set (Ref.Model2, Iter, 0, Get_Int(Ref.Model2, Iter, 0)+1);
475 Put_Line("DEBUG: Calcolo le posizioni scorrette");
476 Iter1 := Get_Iter_First(Ref.Model1);
477 while (Iter1 /= Null_Iter) loop
478 if ( Get_Int(Ref.Model1, Iter1, 1) = Get_Int(Ref.Model2, Iter, 1)) then
479 --Put_Line("DEBUG: Guadagno posizioni auto "&Get_Int(Ref.Model1, Iter1, 1)'Img&": "&ChangePosition(CarId_T(Get_Int(Ref.Model1, Iter1, 1)))'Img);
480 --colora
481 if ( ChangePosition(CarId_T(Get_Int(Ref.Model1, Iter1, 1)))< 0) then
482 -- coloro di verde la posizione
483 Set (Ref.Model1, Iter1, 4, "light green");
484 elsif ( ChangePosition(CarId_T(Get_Int(Ref.Model1, Iter1, 1)))= 0) then
485 Set (Ref.Model1, Iter1, 4, "white");
486 else
487 Set (Ref.Model1, Iter1, 4, "red");
488 end if;
489 end if;
490 Next(Ref.Model1, Iter1);
491 end loop;
492 Next(Ref.Model2, Iter);
493 end loop;
494 end if;
495 Gdk.Threads.Leave;
496 end Update_Model;
498 procedure Update_BestLap(Id : CarId_T; Lap : Positive; Time : Duration) is
499 m : Integer;
500 s : Integer;
501 c : Integer;
502 begin
503 -- Put_Line("Update monitor's best lap.");
504 Ref.BestLap := Time;
505 Ref.BestLap_Id := Id;
506 Ref.BestLap_Lap := Lap;
507 m := Integer(Float'Truncation(Float(Time)/60.0));
508 s := Integer(Float'Truncation(Float(Time))) - m*60;
509 c := Integer(Float'Truncation(Float(Time * 1000))) - m*60000 -s *1000;
510 Set_Text(Ref.BestLap_Info, "Best Lap: "&m'Img&":"&s'Img&"."&c'Img &" Car: "&Id'Img&" on lap "&Lap'Img);
511 end Update_BestLap;
513 procedure Update_MaxSpeed(Id : CarId_T; Val : Float) is
514 StrSpeed : String := "vvvvvv";
515 begin
516 -- Put_Line("Update monitor's max speed.");
517 Ref.MaxSpeed := Val;
518 Ref.MaxSpeed_Id := Id;
519 Put(StrSpeed, Val*3.6, Aft => 2, Exp => 0);
520 Set_Text(Ref.MaxSpeed_Info, "Max Speed: "&StrSpeed&" km/h Car: "&Id'Img);
521 end Update_MaxSpeed;
523 procedure ToggleLock (Widget : access Gtk_Widget_Record'Class) is
524 begin
525 Ref.Observing := not Ref.Observing;
526 if (Ref.Observing) then
527 Set_Label(Ref.Lock, "Unlock");
528 else
529 Set_Label(Ref.Lock, "Lock");
530 end if;
531 end ToggleLock;
533 procedure EndRace is
534 ans : Message_Dialog_Buttons;
535 begin
536 Gdk.Threads.Enter;
537 ans := Message_Dialog("Race Finished !", Buttons => Button_OK);
538 Gdk.Threads.Leave;
539 end EndRace;
541 end Simulator.Monitor.Gui;