100 lines
4.0 KiB
Ada
100 lines
4.0 KiB
Ada
with Ada.Numerics.Elementary_Functions;
|
|
with Ada.Calendar.Formatting;
|
|
with Ada.Calendar.Time_Zones;
|
|
|
|
with SDL.Video.Windows.Makers;
|
|
with SDL.Video.Renderers.Makers;
|
|
with SDL.Events.Events;
|
|
|
|
procedure Draw_A_Clock is
|
|
use Ada.Calendar;
|
|
use Ada.Calendar.Formatting;
|
|
Window : SDL.Video.Windows.Window;
|
|
Renderer : SDL.Video.Renderers.Renderer;
|
|
Event : SDL.Events.Events.Events;
|
|
Offset : Time_Zones.Time_Offset;
|
|
|
|
procedure Draw_Clock (Stamp : Time)
|
|
is
|
|
use SDL.C;
|
|
use Ada.Numerics.Elementary_Functions;
|
|
Radi : constant array (0 .. 59) of int := (0 | 15 | 30 | 45 => 2,
|
|
5 | 10 | 20 | 25 | 35 | 40 | 50 | 55 => 1,
|
|
others => 0);
|
|
Diam : constant array (0 .. 59) of int := (0 | 15 | 30 | 45 => 5,
|
|
5 | 10 | 20 | 25 | 35 | 40 | 50 | 55 => 3,
|
|
others => 1);
|
|
Width : constant int := Window.Get_Surface.Size.Width;
|
|
Height : constant int := Window.Get_Surface.Size.Height;
|
|
Radius : constant Float := Float (int'Min (Width, Height));
|
|
R_1 : constant Float := 0.48 * Radius;
|
|
R_2 : constant Float := 0.35 * Radius;
|
|
R_3 : constant Float := 0.45 * Radius;
|
|
R_4 : constant Float := 0.47 * Radius;
|
|
Hour : constant Hour_Number := Formatting.Hour (Stamp, Offset);
|
|
Minute : constant Minute_Number := Formatting.Minute (Stamp, Offset);
|
|
Second : constant Second_Number := Formatting.Second (Stamp);
|
|
|
|
function To_X (A : Float; R : Float) return int is
|
|
(Width / 2 + int (R * Sin (A, 60.0)));
|
|
|
|
function To_Y (A : Float; R : Float) return int is
|
|
(Height / 2 - int (R * Cos (A, 60.0)));
|
|
|
|
begin
|
|
SDL.Video.Renderers.Makers.Create (Renderer, Window.Get_Surface);
|
|
Renderer.Set_Draw_Colour ((0, 0, 150, 255));
|
|
Renderer.Fill (Rectangle => (0, 0, Width, Height));
|
|
Renderer.Set_Draw_Colour ((200, 200, 200, 255));
|
|
for A in 0 .. 59 loop
|
|
Renderer.Fill (Rectangle => (To_X (Float (A), R_1) - Radi (A),
|
|
To_Y (Float (A), R_1) - Radi (A), Diam (A), Diam (A)));
|
|
end loop;
|
|
Renderer.Set_Draw_Colour ((200, 200, 0, 255));
|
|
Renderer.Draw (Line => ((Width / 2, Height / 2),
|
|
(To_X (5.0 * (Float (Hour) + Float (Minute) / 60.0), R_2),
|
|
To_Y (5.0 * (Float (Hour) + Float (Minute) / 60.0), R_2))));
|
|
Renderer.Draw (Line => ((Width / 2, Height / 2),
|
|
(To_X (Float (Minute) + Float (Second) / 60.0, R_3),
|
|
To_Y (Float (Minute) + Float (Second) / 60.0, R_3))));
|
|
Renderer.Set_Draw_Colour ((220, 0, 0, 255));
|
|
Renderer.Draw (Line => ((Width / 2, Height / 2),
|
|
(To_X (Float (Second), R_4),
|
|
To_Y (Float (Second), R_4))));
|
|
Renderer.Fill (Rectangle => (Width / 2 - 3, Height / 2 - 3, 7, 7));
|
|
end Draw_Clock;
|
|
|
|
function Poll_Quit return Boolean is
|
|
use type SDL.Events.Event_Types;
|
|
begin
|
|
while SDL.Events.Events.Poll (Event) loop
|
|
if Event.Common.Event_Type = SDL.Events.Quit then
|
|
return True;
|
|
end if;
|
|
end loop;
|
|
return False;
|
|
end Poll_Quit;
|
|
|
|
begin
|
|
Offset := Time_Zones.UTC_Time_Offset;
|
|
|
|
if not SDL.Initialise (Flags => SDL.Enable_Screen) then
|
|
return;
|
|
end if;
|
|
|
|
SDL.Video.Windows.Makers.Create (Win => Window,
|
|
Title => "Draw a clock",
|
|
Position => SDL.Natural_Coordinates'(X => 10, Y => 10),
|
|
Size => SDL.Positive_Sizes'(300, 300),
|
|
Flags => SDL.Video.Windows.Resizable);
|
|
loop
|
|
Draw_Clock (Clock);
|
|
Window.Update_Surface;
|
|
delay 0.200;
|
|
exit when Poll_Quit;
|
|
end loop;
|
|
|
|
Window.Finalize;
|
|
SDL.Finalise;
|
|
end Draw_A_Clock;
|