File : klokka_gui.adb
----------------------------------------------------------------------------
-- Klokka --
-- Copyright (C) 2002 --
-- Preben Randhol --
-- License: Gnat Modified GNU Public License --
-- --
-- This program is free software; you can redistribute it and/or --
-- modify it under the terms of the GNU General Public License as --
-- published by the Free Software Foundation; either version 2 of the --
-- License, or (at your option) any later version. --
-- --
-- This program is distributed in the hope that it will be useful, --
-- but WITHOUT ANY WARRANTY; without even the implied warranty of --
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU --
-- General Public License for more details. --
-- --
-- You should have received a copy of the GNU General Public License --
-- along with this program; if not, write to the Free Software --
-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA --
-- 02111-1307, USA. --
-- --
-- As a special exception, if other files instantiate generics from --
-- this unit, or you link this unit with other files to produce an --
-- executable, this unit does not by itself cause the resulting --
-- executable to be covered by the GNU General Public License. This --
-- exception does not however invalidate any other reasons why the --
-- executable file might be covered by the GNU Public License. --
-- --
----------------------------------------------------------------------------
with Glib; use Glib;
with Gtk.Enums; use Gtk.Enums;
with Gtk; use Gtk;
with Gdk.Types; use Gdk.Types;
with Gdk.Bitmap; use Gdk.Bitmap;
with Gdk.Drawable; use Gdk.Drawable;
with Gtk.Widget; use Gtk.Widget;
with Gtk.Enums; use Gtk.Enums;
with Gtkada.Handlers; use Gtkada.Handlers;
with Callbacks_Klokka; use Callbacks_Klokka;
with Ada.Numerics; use Ada.Numerics;
with Ada.Calendar; use Ada.Calendar;
with Klokka_Pixmap;
package body Klokka_Gui is
procedure Make
is
begin
Klokka_Gui.Gtk_New (Klokka_Gui.Window);
Klokka_Gui.Show_All (Klokka_Gui.Window);
Klokka_Gui.Clock_Init (Klokka_Gui.Window);
end Make;
procedure Gtk_New (Window : out Window_Access) is
begin
Window := new Window_Record;
Klokka_Gui.Initialize (Window);
end Gtk_New;
procedure Clock_Init (Window : access Window_Record'Class) is
Mask : Gdk.Bitmap.Gdk_Bitmap;
Success : Boolean;
begin
Window.Draw_Window := Gtk.Drawing_Area.Get_Window (Window.Drawing_Area);
Set_Rgb (Window.Light_Grey_Color, 46_848, 44_056, 26_112);
Alloc_Color (Colormap => Gtk.Widget.Get_Default_Colormap,
Color => Window.Light_Grey_Color,
Writeable => False,
Best_Match => True,
Success => Success);
Set_Rgb (Window.Grey_Color, 22_016, 20_248, 12_544);
Alloc_Color (Colormap => Gtk.Widget.Get_Default_Colormap,
Color => Window.Grey_Color,
Writeable => False,
Best_Match => True,
Success => Success);
Set_Rgb (Window.Red_Color, 38_535, 0, 0);
Alloc_Color (Colormap => Gtk.Widget.Get_Default_Colormap,
Color => Window.Red_Color,
Writeable => False,
Best_Match => True,
Success => Success);
Gdk_New (Window.Clock_GC, Window.Draw_Window);
Create_From_Xpm_D
(Pixmap => Window.Background_Pixmap,
Window => Window.Draw_Window,
Mask => Mask,
Transparent => Gdk.Color.Null_Color,
Data => Klokka_Pixmap.Klokka_Xpm);
Gdk_New
(Pixmap => Window.Pixmap_Buffer,
Window => Window.Draw_Window,
Width => 71,
Height => 73);
Gdk_New
(Pixmap => Window.Pixmap,
Window => Window.Draw_Window,
Width => 71,
Height => 73);
end Clock_Init;
procedure Draw_Clock is
begin
Draw_Pixmap
(Drawable => Window.Draw_Window,
Gc => Window.Clock_GC,
Src => Window.Pixmap,
Xsrc => 0,
Ysrc => 0,
Xdest => 0,
Ydest => 0);
end Draw_Clock;
procedure Update_Clock is
Deg_To_Rad : constant := Pi / 180;
Sec_To_Deg : constant := 15;
Hrs_To_Sec : constant := 5.0;
X : constant := 35;
Y : constant := 36;
Hour_Radius : constant := 9.0;
Min_Radius : constant := Hour_Radius + 6.0;
Sec_Radius : constant := Min_Radius + 3.0;
Handle_Thickness : constant := 3;
Year : Year_Number;
Month : Month_Number;
Day : Day_Number;
Seconds : Natural;
S : Day_Duration;
Hour : Float;
Min : Natural;
Sec : Natural;
Hour_X2 : Gint;
Hour_Y2 : Gint;
Min_X2 : Gint;
Min_Y2 : Gint;
Sec_X2 : Gint;
Sec_Y2 : Gint;
begin
Draw_Pixmap
(Drawable => Window.Pixmap_Buffer,
Gc => Window.Clock_GC,
Src => Window.Background_Pixmap,
Xsrc => 0,
Ysrc => 0,
Xdest => 0,
Ydest => 0);
Split (Date => Clock,
Year => Year,
Month => Month,
Day => Day,
Seconds => S);
Seconds := Natural (S);
Sec := Seconds rem 60;
Min := (Seconds / 60) rem 60;
Hour := (Float (Seconds) / 3600.0);
-- Using Float for Hour because I need the hour-handle to move
-- also between the hours otherwise it is even harder to read the
-- time.
Hour_X2 := X - Gint (Hour_Radius *
Cos ((Hour * Hrs_To_Sec + Float (Sec_To_Deg)) * 6.0 * Deg_To_Rad));
Hour_Y2 := Y - Gint (Hour_Radius *
Sin ((Hour * Hrs_To_Sec + Float (Sec_To_Deg)) * 6.0 * Deg_To_Rad));
Min_X2 := X - Gint (Min_Radius *
Cos (Float ((Min + Sec_To_Deg) * 6) * Deg_To_Rad));
Min_Y2 := Y - Gint (Min_Radius *
Sin (Float ((Min + Sec_To_Deg) * 6) * Deg_To_Rad));
Sec_X2 := X - Gint (Sec_Radius *
Cos (Float ((Sec + Sec_To_Deg) * 6) * Deg_To_Rad));
Sec_Y2 := Y - Gint (Sec_Radius *
Sin (Float ((Sec + Sec_To_Deg) * 6) * Deg_To_Rad));
-- First we draw the hour and minute handles with a light colour
-- and 2 pixels wider than what we want the handles to be to get
-- an antialias effect. If we don't do this the handles look
-- ugly.
Set_Line_Attributes
(GC => Window.Clock_GC,
Line_Width => Handle_Thickness + 2,
Line_Style => Line_Solid,
Cap_Style => Cap_Projecting,
Join_Style => Join_Miter);
Set_Foreground
(GC => Window.Clock_GC,
Color => Window.Light_Grey_Color);
Draw_Line
(Drawable => Window.Pixmap_Buffer,
Gc => Window.Clock_GC,
X1 => X,
Y1 => Y,
X2 => Min_X2,
Y2 => Min_Y2);
Draw_Line
(Drawable => Window.Pixmap_Buffer,
Gc => Window.Clock_GC,
X1 => X,
Y1 => Y,
X2 => Hour_X2,
Y2 => Hour_Y2);
-- Now we draw the hour and minute handles with a darker colour
-- and 1 pixels wider for the antialias effect.
Set_Line_Attributes
(GC => Window.Clock_GC,
Line_Width => Handle_Thickness + 1,
Line_Style => Line_Solid,
Cap_Style => Cap_Projecting,
Join_Style => Join_Miter);
Set_Foreground
(GC => Window.Clock_GC,
Color => Window.Grey_Color);
Draw_Line
(Drawable => Window.Pixmap_Buffer,
Gc => Window.Clock_GC,
X1 => X,
Y1 => Y,
X2 => Min_X2,
Y2 => Min_Y2);
Draw_Line
(Drawable => Window.Pixmap_Buffer,
Gc => Window.Clock_GC,
X1 => X,
Y1 => Y,
X2 => Hour_X2,
Y2 => Hour_Y2);
-- Finally we draw the hour and minute handles with a black
-- colour.
Set_Line_Attributes
(GC => Window.Clock_GC,
Line_Width => Handle_Thickness,
Line_Style => Line_Solid,
Cap_Style => Cap_Projecting,
Join_Style => Join_Miter);
Set_Foreground
(GC => Window.Clock_GC,
Color => Black (Gtk.Widget.Get_Default_Colormap));
Draw_Line
(Drawable => Window.Pixmap_Buffer,
Gc => Window.Clock_GC,
X1 => X,
Y1 => Y,
X2 => Min_X2,
Y2 => Min_Y2);
Draw_Line
(Drawable => Window.Pixmap_Buffer,
Gc => Window.Clock_GC,
X1 => X,
Y1 => Y,
X2 => Hour_X2,
Y2 => Hour_Y2);
-- Drawing the second handle. This is only a pixel thick so we
-- cannot use antialiasing here.
Set_Line_Attributes
(GC => Window.Clock_GC,
Line_Width => 1,
Line_Style => Line_Solid,
Cap_Style => Cap_Projecting,
Join_Style => Join_Miter);
Set_Foreground
(GC => Window.Clock_GC,
Color => Window.Red_Color);
Draw_Line
(Drawable => Window.Pixmap_Buffer,
Gc => Window.Clock_GC,
X1 => X,
Y1 => Y,
X2 => Sec_X2,
Y2 => Sec_Y2);
Draw_Pixmap
(Drawable => Window.Pixmap,
Gc => Window.Clock_GC,
Src => Window.Pixmap_Buffer,
Xsrc => 0,
Ysrc => 0,
Xdest => 0,
Ydest => 0);
end Update_Clock;
procedure Initialize (Window : access Window_Record'Class) is
begin
Gtk.Window.Initialize (Window, Window_Toplevel);
Set_Title (Window, "Klokka");
Set_Policy (Window, False, False, True);
Set_Position (Window, Win_Pos_None);
Set_Modal (Window, False);
Set_Sensitive (Window, True);
Gtk_New_Vbox (Window.Base_Vbox, False, 0);
Add (Window, Window.Base_Vbox);
Gtk_New (Window.Drawing_Area);
Size (Window.Drawing_Area, 71, 73);
Pack_Start (Window.Base_Vbox, Window.Drawing_Area, True, True, 0);
Return_Callback.Connect
(Gtk_Widget (Window), "delete_event",
Callbacks_Klokka.On_Window_Delete_Event'Access);
Event_Cb.Connect
(Gtk_Widget (Window.Drawing_Area), "expose_event",
Event_Cb.To_Marshaller (
On_Window_Expose_Event'Access));
end Initialize;
end Klokka_Gui;