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
;
6 with Gtk
.Main
; use Gtk
.Main
;
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
);
24 Simulator
.Monitor
.Quit
;
26 Put_Line
("GUI: delete event occurred");
30 procedure Destroy
(Widget
: access Gtk_Widget_Record
'Class) is
31 pragma Unreferenced
(Widget
);
37 procedure Gtk_New
(Monitor
: out Monitor_Access
) is
39 Monitor
:= new Monitor_Record
;
41 Simulator
.Monitor
.Gui
.Initialize
(Monitor
);
44 procedure Initialize
(Monitor
: access Monitor_Record
'Class) is
45 pragma Suppress
(All_Checks
);
46 Pixmaps_Dir
: constant String := "pixmaps/";
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
);
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
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
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
);
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);
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
);
158 Gtk_New
(Monitor
.Frame2
);
159 Set_Label_Align
(Monitor
.Frame2
, 0.0, 0.5);
160 Set_Shadow_Type
(Monitor
.Frame2
, Shadow_Etched_In
);
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);
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));
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
);
257 Monitor
.Scrolledwindow2
,
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
);
280 Gtk_New
(Monitor
.Frame3
);
281 Set_Label_Align
(Monitor
.Frame3
, 0.0, 0.5);
282 Set_Shadow_Type
(Monitor
.Frame3
, Shadow_Etched_In
);
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);
309 Monitor
.BestLap_Info
,
316 Monitor
.MaxSpeed_Info
,
321 Add
(Monitor
.Alignment3
, Monitor
.HBox3
);
337 Add
(Monitor
, Monitor
.Vbox2
);
338 Set_Size_Request
(Monitor
, 600, 350);
341 procedure Update_Model
(Pos
: Positive;
344 Intermediate
: Natural;
345 WakeupTime
: Duration;
348 BestLap
: Duration) is
349 Iter
: Gtk_Tree_Iter
;
350 Iter1
: Gtk_Tree_Iter
;
352 StrTime
: String := "tttttttttt";
353 StrVel
: String := "vvvvvvvv";
359 -- disabilito ordinamento automatico
361 -- Put_Line("Update gui-monitor's data. Id: " & CarId'Img & ", Pos: " & Pos'Img & ".");
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
);
369 if (Iter
/= Null_Iter
) then
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);
382 Set
(Ref
.Model1
, Iter
, 5, "--");
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);
390 Set
(Ref
.Model1
, Iter
, 6, "--");
393 if( Pos
- OldPos
= 0) then
394 ChangePosition
(CarId
) := 0;
396 ChangePosition
(CarId
) :=ChangePosition
(CarId
)+ Pos
- OldPos
;
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");
405 Set
(Ref
.Model1
, Iter
, 4, "white");
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");
422 Set
(Ref
.Model1
, Iter
, 4, "red");
427 Next
(Ref
.Model1
, Iter
);
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, "--");
442 -- aggiorno i valori massimi
443 if ((Lap
> Ref
.LastLap
or ((Lap
= Ref
.LastLap
) and (Intermediate
> Ref
.LastInt
))) and Ref
.Observing
= False) then
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
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
));
462 Set
(Ref
.Model2
, Iter
, 2, " "&StrTime
&" ");
464 DurationIO
.Put
(StrTime
, (WakeupTime
- Ref
.LastTime
), Aft
=> 3);
465 Set
(Ref
.Model2
, Iter
, 2, "+ "&StrTime
&" s");
467 Put
(StrVel
, Vel
*3.6, Aft
=> 2, Exp
=> 0);
468 Set
(Ref
.Model2
, Iter
, 3, StrVel
&" km/h");
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);
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");
487 Set
(Ref
.Model1
, Iter1
, 4, "red");
490 Next
(Ref
.Model1
, Iter1
);
492 Next
(Ref
.Model2
, Iter
);
498 procedure Update_BestLap
(Id
: CarId_T
; Lap
: Positive; Time
: Duration) is
503 -- Put_Line("Update monitor's best lap.");
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);
513 procedure Update_MaxSpeed
(Id
: CarId_T
; Val
: Float) is
514 StrSpeed
: String := "vvvvvv";
516 -- Put_Line("Update monitor's max speed.");
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);
523 procedure ToggleLock
(Widget
: access Gtk_Widget_Record
'Class) is
525 Ref
.Observing
:= not Ref
.Observing
;
526 if (Ref
.Observing
) then
527 Set_Label
(Ref
.Lock
, "Unlock");
529 Set_Label
(Ref
.Lock
, "Lock");
534 ans
: Message_Dialog_Buttons
;
537 ans
:= Message_Dialog
("Race Finished !", Buttons
=> Button_OK
);
541 end Simulator
.Monitor
.Gui
;